From abe634cfe3cd97675de06606146c7ac570c989c5 Mon Sep 17 00:00:00 2001 From: Packit Service Date: Dec 09 2020 12:35:29 +0000 Subject: driverctl-0.111 base --- diff --git a/05-driverctl.rules b/05-driverctl.rules new file mode 100644 index 0000000..539ba80 --- /dev/null +++ b/05-driverctl.rules @@ -0,0 +1,2 @@ + +ACTION=="add", TEST=="/etc/driverctl.d/$env{SUBSYSTEM}-$kernel", TAG+="systemd", ENV{SYSTEMD_WANTS}="driverctl@$env{SUBSYSTEM}-$kernel.service" diff --git a/89-vfio-uio.rules b/89-vfio-uio.rules new file mode 100644 index 0000000..bafa529 --- /dev/null +++ b/89-vfio-uio.rules @@ -0,0 +1,5 @@ +ACTION=="add", SUBSYSTEM=="vfio", TAG+="systemd", PROGRAM="/usr/lib/udev/vfio_name %k", ENV{SYSTEMD_ALIAS}+="$result" + +# XXX should we also rename uio devices? Probably... +ACTION=="add", SUBSYSTEM=="uio", TAG+="systemd" + diff --git a/COPYING b/COPYING new file mode 100644 index 0000000..4362b49 --- /dev/null +++ b/COPYING @@ -0,0 +1,502 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 2.1, February 1999 + + Copyright (C) 1991, 1999 Free Software Foundation, Inc. + 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[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. + + GNU LESSER GENERAL PUBLIC LICENSE + 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 + + 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 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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/Makefile b/Makefile new file mode 100644 index 0000000..1a269df --- /dev/null +++ b/Makefile @@ -0,0 +1,55 @@ +PREFIX=/usr +UDEVDIR=$(shell pkg-config --variable=udevdir udev) +UNITDIR=$(shell pkg-config --variable=systemdsystemunitdir systemd) +SBINDIR=$(PREFIX)/sbin +CONFDIR=/etc/driverctl.d +MANDIR=$(PREFIX)/share/man/ +BASHDIR=$(PREFIX)/share/bash-completion +NAME=driverctl +VERSION=0.$(shell git rev-list --count HEAD) +COMMIT=$(shell git rev-list --max-count 1 HEAD) +NVFMT=$(NAME)-$(VERSION)-$(COMMIT) + +files: driverctl driverctl.8 driverctl-bash-completion.sh driverctl@.service 05-driverctl.rules \ + README COPYING TODO \ + 89-vfio-uio.rules vfio_name \ + driverctl.spec.in Makefile + +archive: files tag driverctl.spec + git archive --prefix=$(NVFMT)/ HEAD > $(NVFMT).tar + tar -r -f $(NVFMT).tar --transform "s:^:$(NVFMT)/:" driverctl.spec + gzip -f -9 $(NVFMT).tar + +driverctl.spec: driverctl.spec.in files + sed -e 's:#VERSION#:$(VERSION):g' \ + -e 's:#COMMIT#:$(COMMIT):g' < driverctl.spec.in > driverctl.spec + git log --format="* %cd %aN <%ae>%n%B" --date=local driverctl.spec.in | sed -r -e 's/%/%%/g' -e 's/[0-9]+:[0-9]+:[0-9]+ //' >> driverctl.spec + +srpm: driverctl.spec archive + rpmbuild -bs --define "_sourcedir $(PWD)" --define "_specdir $(PWD)" --define "_builddir $(PWD)" --define "_srcrpmdir $(PWD)" --define "_rpmdir $(PWD)" driverctl.spec + +rpm: driverctl.spec archive + rpmbuild -bb --define "_sourcedir $(PWD)" --define "_specdir $(PWD)" --define "_builddir $(PWD)" --define "_srcrpmdir $(PWD)" --define "_rpmdir $(PWD)" driverctl.spec + +install: + # driverctl + mkdir -p $(DESTDIR)$(CONFDIR) + mkdir -p $(DESTDIR)$(UDEVDIR)/rules.d/ + install -m 644 05-driverctl.rules $(DESTDIR)$(UDEVDIR)/rules.d/ + mkdir -p $(DESTDIR)$(UNITDIR) + install -m 644 driverctl@.service $(DESTDIR)$(UNITDIR)/ + mkdir -p $(DESTDIR)$(SBINDIR) + install -m 755 driverctl $(DESTDIR)$(SBINDIR)/ + mkdir -p $(DESTDIR)$(BASHDIR)/completions/ + install -m 644 driverctl-bash-completion.sh $(DESTDIR)$(BASHDIR)/completions/driverctl + mkdir -p $(DESTDIR)$(MANDIR)/man8 + install -m 644 driverctl.8 $(DESTDIR)$(MANDIR)/man8/ + # misc vfio/uio bits, dont really belong here... + install -m 644 89-vfio-uio.rules $(DESTDIR)$(UDEVDIR)/rules.d/ + install -m 755 vfio_name $(DESTDIR)$(UDEVDIR)/ + +clean: + rm -f driverctl.spec *.src.rpm noarch/*.rpm *.tar.gz + +tag: + git tag -l $(VERSION) | grep -q $(VERSION) || git tag $(VERSION) diff --git a/README b/README new file mode 100644 index 0000000..c4b0337 --- /dev/null +++ b/README @@ -0,0 +1,100 @@ +driverctl is a device driver control utility for Linux + +Description +----------- + +driverctl is a tool for manipulating and inspecting the system +device driver choices. + +Devices are normally assigned to their sole designated kernel driver +by default. However in some situations it may be desireable to +override that default, for example to try an older driver to +work around a regression in a driver or to try an experimental alternative +driver. Another common use-case is pass-through drivers and driver +stubs to allow userspace to drive the device, such as in case of +virtualization. + +driverctl integrates with udev to support overriding +driver selection for both cold- and hotplugged devices from the +moment of discovery, but can also change already assigned drivers, +assuming they are not in use by the system. The driver overrides +created by driverctl are persistent across system reboots +by default. + +License +------- + +Licensed under the GNU Lesser General Public License aka LGPL v2.1. +See COPYING for details. + +Source repository +----------------- + +git clone https://gitlab.com/driverctl/driverctl.git + +System requirements +------------------- + +- udev, tested with versions >= 219 but older versions are likely + to work as well +- kernel >= 3.16 or backported support for driver_override device + binding path: + https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=782a985d7af26db39e86070d28f987cad21313c0 +- bash-completion (optional) + +Installation +------------ + +"make rpm" should create a working package to be installed for those on +rpm-based distros (tested on recent Fedora and RHEL 7), others should +be able to use "make install" (but note there's no "uninstall" target) + +Usage +----- + +Find devices currently driven by ixgbe driver: + +# driverctl -v list-devices | grep ixgbe +0000:01:00.0 ixgbe (Ethernet 10G 4P X520/I350 rNDC) +0000:01:00.1 ixgbe (Ethernet 10G 4P X520/I350 rNDC) + +Change them to use the vfio-pci driver: +# driverctl set-override 0000:01:00.0 vfio-pci +# driverctl set-override 0000:01:00.1 vfio-pci + +Find devices with driver overrides: +# driverctl -v list-overrides +0000:01:00.0 vfio-pci (Ethernet 10G 4P X520/I350 rNDC) +0000:01:00.1 vfio-pci (Ethernet 10G 4P X520/I350 rNDC) + +Find network devices: +# driverctl list-devices network +0000:01:00.0 ixgbe +0000:01:00.1 ixgbe +0000:06:00.0 igb +0000:06:00.1 igb + +Remove the override from slot 0000:01:00.1: +# driverctl unset-override 0000:01:00.1 + +Extras +------ + +In addition to the actual driverctl utility, udev rules to expose +VFIO and UIO devices on systemd level are included to make them +dependable for services. + +Since the vfio device naming is based on IOMMU groups it is rather +unpredictable on the outset: for example on my laptop the NIC at +PCI slot 0000:00:19.0 would appear as /sys/devices/virtual/vfio/3 +when bound to the vfio_pci driver. To make this more discoverable, +systemd aliases are added so the device is additionally addressable +by its PCI slot name, in this example it'd be: +sys-devices-pci0000:00-0000:00:19.0-vfio.device. + +Contributing etc +---------------- + +Patches, bug reports and other feedback are welcome via the +project page: https://gitlab.com/driverctl/driverctl + diff --git a/TODO b/TODO new file mode 100644 index 0000000..2aac8f9 --- /dev/null +++ b/TODO @@ -0,0 +1,17 @@ +Limitations / future ideas +-------------------------- + +- PCI slot numbers are not really static, it'd be good to support some + other means of addressing a given device. However prior to loading + an actual driver there isn't much data to go on with, just about + the only thing is the actual pci-id which *is* static and reliable + but using it'd mean overriding all such devices. Which might be a + better option than not being able to do it at all. +- Rewrite it in some real programming language +- In current kernels (as of 4.6.x) very limited number of subsystems + support driver_override. The rest could be supported if we used + the older unbind/bind mechanism, but I'm lazy. +- Some devices might need overriding in the initrd phase already, + add dracut integration +- Rewrite in an actual programming language (read: C) + diff --git a/driverctl b/driverctl new file mode 100755 index 0000000..3342393 --- /dev/null +++ b/driverctl @@ -0,0 +1,270 @@ +#!/bin/bash + +confdir=/etc/driverctl.d +bus=${SUBSYSTEM:-pci} +probe=1 +save=1 +debug=0 + +declare -A devclasses +devclasses=(["all"]="" + ["storage"]="01" + ["network"]="02" + ["display"]="03" + ["multimedia"]="04" + ["memory"]="05" + ["bridge"]="06" + ["communication"]="07" + ["system"]="08" + ["input"]="09" + ["docking"]="0a" + ["processor"]="0b" + ["serial"]="0c" +) + +function log() +{ + echo "driverctl: $*" >&2 +} + +function debug() +{ + [ "$debug" -ne 0 ] && log "$@" +} + +function error() +{ + log "$@" + exit 1 +} + +function usage() +{ + echo "Usage: driverctl [OPTIONS...] {COMMAND}..." + echo + echo "Inspect or control default device driver bindings." + echo + echo "Supported commands:" + echo " set-override Make the default driver" + echo " for " + echo " unset-override Remove any override for " + echo " load-override Load an override previously specified" + echo " for " + echo " list-devices List all overridable devices" + echo " list-overrides List all currently specified overrides" + echo + echo "Supported options:" + echo " -h --help Show this help" + echo " -v --verbose --debug Show verbose debug information" + echo " -b --bus Work on bus (default pci)" + echo " --noprobe Do not reprobe when setting, unsetting, or" + echo " loading an override" + echo " --nosave Do not save changes when setting or unsetting" + echo " an override" + echo "" +} + +function unbind() +{ + if [ -L "$syspath/driver" ]; then + debug "unbinding previous driver $(basename "$(readlink "$syspath/driver")")" + if ! echo "$dev" > "$syspath/driver/unbind"; then + error "unbinding $dev failed" + fi + else + debug "device $dev not bound" + fi +} + +function probe_driver() +{ + debug "reprobing driver for $dev" + echo "$dev" > "/sys/bus/$bus/drivers_probe" +} + +function save_override() +{ + debug "saving driver override for $dev" + if [ -n "$drv" ]; then + [ -d "$confdir" ] || mkdir -p "$confdir" + echo "$drv" > "$confdir/$sddev" + else + rm -f "$confdir/$sddev" + fi +} + +function list_devices() +{ + devices=() + for d in "/sys/bus/$bus/devices"/*; do + if [ -f "$d/driver_override" ]; then + override="$(< "$d/driver_override")" + if [ "$1" -eq 1 ] && [ "$override" == "(null)" ]; then + continue + fi + + line="$(basename "$d")" + devices+=("$line") + + if [ -n "$2" ]; then + class="$(< "$d/class")" + [ "$2" == "${class:2:2}" ] || continue + fi + if [ -L "$d/driver" ]; then + line+=" $(basename "$(readlink "$d/driver")")" + else + line+=" (none)" + fi + if [ "$1" -ne 1 ] && [ "$override" != "(null)" ]; then + line+=" [*]" + fi + + if [ $debug -ne 0 ]; then + line+=" ($(udevadm info -q property "$d" | grep ID_MODEL_FROM_DATABASE | cut -d= -f2))" + fi + echo "$line" + fi + done + if [ ${#devices[@]} -eq 0 ]; then + error "No overridable devices found. Kernel too old?" + fi +} + +function set_override() +{ + if [ ! -f "$syspath/driver_override" ]; then + error "device does not support driver override: $dev" + fi + if [ -n "$drv" ] && [ "$drv" != "none" ]; then + debug "setting driver override for $dev: $drv" + if [ ! -d "/sys/module/$drv" ]; then + debug "loading driver $drv" + /sbin/modprobe -q "$drv" || error "no such module: $drv" + fi + else + debug "unsetting driver override for $dev" + fi + unbind + echo "$drv" > "$syspath/driver_override" + + if [ "$drv" != "none" ] && [ $probe -ne 0 ]; then + probe_driver + if [ ! -L "$syspath/driver" ]; then + error "failed to bind device $dev to driver $drv" + fi + fi +} + +while (($# > 0)); do + case ${1} in + --noprobe) + probe=0 + ;; + --nosave) + save=0 + ;; + --debug|--verbose|-v) + debug=1 + ;; + -b|--bus) + bus=${2} + shift + ;; + -h|--help|-*) + usage + exit 0 + ;; + set-override) + if [ $# -ne 3 ]; then + usage + exit 1 + fi + + cmd=$1 + dev=$2 + drv=$3 + break + ;; + load-override|unset-override) + if [ $# -ne 2 ]; then + usage + exit 1 + fi + + cmd=$1 + dev=$2 + break + ;; + list-devices|list-overrides) + if [ $# -gt 2 ]; then + usage + exit 1 + fi + + if [ -n "$2" ] && [ ! "${devclasses[$2]+_}" ]; then + error "device type must be one of: ${!devclasses[*]}" + fi + cmd=$1 + devtype="${devclasses[${2:-all}]}" + break + ;; + *) + usage + exit 1 + ;; + esac + shift +done + +if [ -z "$cmd" ]; then + usage + exit 1 +fi + +if [ -n "$dev" ]; then + case ${dev} in + */*) + bus=${dev%%/*} + dev=${dev#*/} + ;; + esac + if [ -n "${DEVPATH:-}" ]; then + devpath="$DEVPATH" + else + devlink="/sys/bus/$bus/devices/$dev" + [ -L "$devlink" ] || error "no such device: $dev" + devpath=$(realpath "$devlink" | cut -c5-) + fi + syspath="/sys/$devpath" + sddev="$bus-$dev" +fi + +case ${cmd} in + load-override) + if [ -s "$confdir/$sddev" ]; then + drv=$(< "$confdir/$sddev") + set_override "$dev" "$drv" + else + exit 1 + fi + ;; + list-devices) + list_devices 0 "$devtype" + ;; + list-overrides) + list_devices 1 "$devtype" + ;; + set-override) + set_override "$dev" "$drv" + if [ $save -ne 0 ]; then + save_override + fi + + ;; + unset-override) + set_override "$dev" "" + if [ $save -ne 0 ]; then + save_override + fi + ;; +esac diff --git a/driverctl-bash-completion.sh b/driverctl-bash-completion.sh new file mode 100644 index 0000000..1a906e5 --- /dev/null +++ b/driverctl-bash-completion.sh @@ -0,0 +1,45 @@ +# driverctl completion + +_driverctl() +{ + local cur prev words cword + _init_completion || return + + case $prev in + [0-9][0-9]\.[0-9]) + # may or may not be + return 0 + ;; + [0-9:.]*) + _get_comp_words_by_ref -n : cur + COMPREPLY=($(compgen -W "$(driverctl list-devices | cut -d' ' -f1)" -- "$cur")) + __ltrim_colon_completions "$cur" + return 0 + ;; + --noprobe) + COMPREPLY=($(compgen -W "--bus --nosave --verbose list-devices list-overrides load-override set-override unset-override" -- "$cur")) + return 0 + ;; + --nosave) + COMPREPLY=($(compgen -W "--bus --noprobe --verbose list-devices list-overrides load-override set-override unset-override" -- "$cur")) + return 0 + ;; + --verbose) + COMPREPLY=($(compgen -W "--bus --noprobe --nosave list-devices list-overrides load-override set-override unset-override" -- "$cur")) + return 0 + ;; + load-override|set-override|unset-override) + COMPREPLY=($(compgen -W '$(${1:-driverctl} list-devices | cut -d" " -f1)' -- "$cur")) + return 0 + ;; + list-overrides|list-devices) + COMPREPLY=($(compgen -W "all storage network display multimedia memory bridge communication system input docking processor serial" -- "$cur" )) + return 0 + ;; + driverctl) + COMPREPLY=($(compgen -W "--bus --noprobe --nosave --verbose list-devices list-overrides load-override set-override unset-override" -- "$cur" )) + return 0 + ;; + esac +} +complete -F _driverctl driverctl diff --git a/driverctl.8 b/driverctl.8 new file mode 100644 index 0000000..b9c86b3 --- /dev/null +++ b/driverctl.8 @@ -0,0 +1,157 @@ +.\" driverctl - Device driver control utility +.TH driverctl 8 +.SH NAME +driverctl - Device driver control utility. +.SH SYNOPSIS +\fBdriverctl\fR [OPTIONS] COMMAND [DEVICE [DRIVER]]\fR + +.SH DESCRIPTION + +\fBdriverctl\fR may be used to manipulate and inspect the system +device driver choices. + +Devices are normally assigned to their sole designated kernel driver +by default. However in some situations it may be desireable to +override that default, for example to try an older driver to +work around a regression in a driver or to try an experimental alternative +driver. Another common use-case is pass-through drivers and driver +stubs to allow userspace to drive the device, such as in case of +virtualization. + +\fBdriverctl\fR integrates with \fBudev\fR to support overriding +driver selection for both cold- and hotplugged devices from the +moment of discovery, but can also change already assigned drivers, +assuming they are not in use by the system. The driver overrides +created by \fBdriverctl\fR are persistent across system reboots +by default. + +.SH OPTIONS +.PP +The following options are understood: + +.PP +\fB-b|--bus \fR +.RS 4 +Operate on devices on a given bus, such as \fBpci\fR or \fBusb\fR. +Available options depend on system hardware and kernel, for example +as of kernel 4.6.7 the USB subsystem does not yet support driver_override. +By default \fBpci\fR bus is used. +.RE + +.PP +\fB--debug|--verbose|-v\fR +.RS 4 +Verbose mode, output more detailed information during operation. +.RE + +.PP +\fB-h|--help\fR +.RS 4 +Output usage information. +.RE + +.PP +\fB--noprobe\fR +.RS 4 +Do not (re)probe the device after changing the driver. Applies to +the \fB*-override\fR commands. +.RE + +.PP +\fB--nosave\fR +.RS 4 +Do not set/unset permanently. Applies to \fBset-override\fR and +\fBunset-override\fR commands. +.RE + +.SH COMMANDS + +.PP +The following commands are understood: + +.PP +\fBset-override\fR +.RS 4 +Set a driver override for a device. By default the current driver +is unbound from the device, the new driver is loaded into kernel, +bound and the override is saved permanently. + +As a special case, specifying "none" as the driver will prevent +any driver to be bound to the device until the override is removed. +.RE + +.PP +\fBunset-override\fR +.RS 4 +Unset a driver override for a device. By default the current driver +is unbound from the device, the default driver of the device is bound +and the override is permanently removed. +.RE + +.PP +\fBload-override\fR +.RS 4 +Load a previously set driver override for device from disk. There's +usually no need to invoke this manually, the command exists mostly +for udev interaction. +.RE + +.PP +\fBlist-devices\fR [DEVICETYPE] +.RS 4 +List currently plugged, overridable system devices on a bus (\fBpci\fR +by default) along with their current drivers. Any overridden drivers +are marked with \fB[*]\fR. With \fB-v\fR options, additional device +description from udev database is shown to help identify devices. +It is possible to limit displayed devices by specifying a device type +as an optional argument, for example "network" to list only network devices. +.RE + +.PP +\fBlist-overrides\fR [DEVICETYPE] +.RS 4 +List currently overridden devices on a bus (\fBpci\fR by default) +With \fB-v\fR options, additional device +description from udev database is shown to help identify devices. +It is possible to limit displayed devices by specifying a device type +as an optional argument, for example "network" to list only network devices. +.RE + +.SH "EXIT STATUS" +On success, 0 is returned, a non-zero failure code otherwise. + +.SH EXAMPLES +.nf +Find devices currently driven by \fBixgbe\fR driver: + +# driverctl -v list-devices | grep ixgbe +0000:01:00.0 ixgbe (Ethernet 10G 4P X520/I350 rNDC) +0000:01:00.1 ixgbe (Ethernet 10G 4P X520/I350 rNDC) + +Change them to use the \fBvfio-pci\fR driver: +# driverctl set-override 0000:01:00.0 vfio-pci +# driverctl set-override 0000:01:00.1 vfio-pci + +Find devices with driver overrides: +# driverctl -v list-overrides +0000:01:00.0 vfio-pci (Ethernet 10G 4P X520/I350 rNDC) +0000:01:00.1 vfio-pci (Ethernet 10G 4P X520/I350 rNDC) + +Find network devices: +# driverctl list-devices network +0000:01:00.0 ixgbe +0000:01:00.1 ixgbe +0000:06:00.0 igb +0000:06:00.1 igb + +Remove the override from slot 0000:01:00.1: +# driverctl unset-override 0000:01:00.1 + +.SH FILES +\fI/etc/driverctl.d/*\fR + +.SH "SEE ALSO" +\fBudev\fR(7) +\fBudevadm\fR(8) +\fBlspci\fR(8) +\fBlsusb\fR(8) diff --git a/driverctl.spec.in b/driverctl.spec.in new file mode 100644 index 0000000..c5bab5a --- /dev/null +++ b/driverctl.spec.in @@ -0,0 +1,64 @@ +%global commit #COMMIT# + +Name: driverctl +Version: #VERSION# +Release: 1%{?dist} +Summary: Device driver control utility + +Group: System Environment/Kernel +License: LGPLv2 +URL: https://gitlab.com/driverctl/driverctl +BuildArch: noarch + +# rpm doesn't grok the gitlab url but spectool understands this monster +Source0: https://gitlab.com/OWNER/%{name}/repository/archive.tar.gz?ref=%{version}#/%{name}-%{version}-%{commit}.tar.gz + +# for udev macros +BuildRequires: systemd +Requires(post,postun): %{_sbindir}/udevadm +Requires: coreutils udev + +%description +driverctl is a tool for manipulating and inspecting the system +device driver choices. + +Devices are normally assigned to their sole designated kernel driver +by default. However in some situations it may be desireable to +override that default, for example to try an older driver to +work around a regression in a driver or to try an experimental alternative +driver. Another common use-case is pass-through drivers and driver +stubs to allow userspace to drive the device, such as in case of +virtualization. + +driverctl integrates with udev to support overriding +driver selection for both cold- and hotplugged devices from the +moment of discovery, but can also change already assigned drivers, +assuming they are not in use by the system. The driver overrides +created by driverctl are persistent across system reboots +by default. + +%prep +%setup -q -n %{name}-%{version}-%{commit} + +%install +%make_install + +%files +%license COPYING +%doc README TODO +%{_sbindir}/driverctl +%{_udevrulesdir}/*.rules +%{_udevrulesdir}/../vfio_name +%{_unitdir}/driverctl@.service +%dir %{_sysconfdir}/driverctl.d +%{_datadir}/bash-completion/ +%{_mandir}/man8/driverctl.8* + +%post +%udev_rules_update + +%postun +%udev_rules_update + +%changelog + diff --git a/driverctl@.service b/driverctl@.service new file mode 100644 index 0000000..c971fa0 --- /dev/null +++ b/driverctl@.service @@ -0,0 +1,13 @@ +[Unit] +Description=Load the driverctl override for %i +DefaultDependencies=no +Before=basic.target +RefuseManualStart=yes +RefuseManualStop=yes +ConditionPathExists=/etc/driverctl.d/%i + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=/usr/sbin/driverctl load-override %I +TimeoutStartSec=300 diff --git a/module-setup.sh b/module-setup.sh new file mode 100644 index 0000000..e66687b --- /dev/null +++ b/module-setup.sh @@ -0,0 +1,34 @@ +#!/bin/bash + +driverctl_dir=/etc/driverctl.d/ + +check() +{ + return 0 +} + +depends() +{ + return 0 +} + +installkernel() +{ + for f in ${driverctl_dir}/*; do + mods="" + if [ -s ${f} ]; then + mod=$(cat ${f}) + mods="${mods} ${mod}" + + # hack, but this doesn't get automatically pulled in + [ "${mod}"="vfio-pci" ] && mods="${mods} vfio-iommu-type1" + fi + done + [ -n "$mods" ] && hostonly="" instmods $mods +} + +install() +{ + inst_rules 05-driverctl.rules 89-vfio-uio.rules + inst_multiple ${driverctl_dir}/* /usr/sbin/driverctl /usr/lib/udev/vfio_name /usr/bin/logger +} diff --git a/vfio_name b/vfio_name new file mode 100755 index 0000000..a938cfe --- /dev/null +++ b/vfio_name @@ -0,0 +1,11 @@ +#!/bin/bash + +iog="/sys/kernel/iommu_groups/$(basename "$1")" +test -d "$iog" || exit 1 + +for f in "$iog"/devices/*; do + lnk="$(readlink -f "$f")" + if [ -L "$lnk/driver" ]; then + echo "$lnk/$SUBSYSTEM" + fi +done