pax_global_header00006660000000000000000000000064145647071500014523gustar00rootroot0000000000000052 comment=43d11eac500af48e08ff85dc8f2310e74a431836 diskscan-0.21/000077500000000000000000000000001456470715000132445ustar00rootroot00000000000000diskscan-0.21/.gitignore000066400000000000000000000002251456470715000152330ustar00rootroot00000000000000*.o *.a *.d diskscan arch/arch.c include/arch-internal.h arch/arch.id *~ CMakeCache.txt CMakeFiles cmake_install.cmake install_manifest.txt Makefile diskscan-0.21/CMakeLists.txt000066400000000000000000000054321456470715000160100ustar00rootroot00000000000000cmake_minimum_required(VERSION 3.0.2) project(diskscan VERSION 0.19) export(PACKAGE diskscan) set(PACKAGE_VERSION ${PROJECT_VERSION}) # Default to a debug build if(NOT CMAKE_BUILD_TYPE) set(CMAKE_BUILD_TYPE Debug) endif(NOT CMAKE_BUILD_TYPE) # Pull in zlib find_package(ZLIB REQUIRED) # Ensure clock_gettime can build with or without -lrt as needed include(CheckLibraryExists) CHECK_LIBRARY_EXISTS(rt clock_gettime "time.h" HAVE_CLOCK_GETTIME) if (NOT HAVE_CLOCK_GETTIME) set(CMAKE_EXTRA_INCLUDE_FILES time.h) CHECK_FUNCTION_EXISTS(clock_gettime HAVE_CLOCK_GETTIME) SET(CMAKE_EXTRA_INCLUDE_FILES) else() list(APPEND LIBS rt) endif() # Find tinfo for termcap functions INCLUDE (CheckIncludeFiles) CHECK_INCLUDE_FILES(termcap.h HAVE_TERMCAP_H) find_library(tinfo_LIBRARY NAMES tinfo curses) # Architecture files message("SYSTEM NAME: ${CMAKE_SYSTEM_NAME}") if (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") set(ARCH_SRC "arch/arch-linux.c") set(ARCH_INCLUDE "arch/arch-linux.h") elseif (${CMAKE_SYSTEM_NAME} STREQUAL "kFreeBSD") set(ARCH_SRC "arch/arch-freebsd.c") set(ARCH_INCLUDE "arch/arch-posix.h") elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") set(ARCH_SRC "arch/arch-freebsd.c") set(ARCH_INCLUDE "arch/arch-posix.h") else() set(ARCH_SRC "arch/arch-generic.c") set(ARCH_INCLUDE "arch/arch-posix.h") endif() add_custom_command(OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/include/arch-internal.h COMMAND ln -fs ${CMAKE_CURRENT_SOURCE_DIR}/${ARCH_INCLUDE} ${CMAKE_CURRENT_SOURCE_DIR}/include/arch-internal.h ) # Build diskscan include_directories("include") add_compile_options(-Wall -Wextra -Wshadow -Wmissing-prototypes -Winit-self) add_definitions(-D_GNU_SOURCE -D_FORTIFY_SOURCE=2) add_definitions(-DVERSION="${PROJECT_VERSION}") include_directories(.) include_directories(progressbar/include) # Build libscsicmd for diskscan include_directories(libscsicmd/include) add_subdirectory(libscsicmd/src) # Build diskscan library add_library(diskscanlib STATIC lib/data.c lib/diskscan.c lib/sha1.c lib/system_id.c lib/verbose.c lib/disk.c hdrhistogram/src/hdr_histogram.c hdrhistogram/src/hdr_histogram_log.c hdrhistogram/src/hdr_encoding.c ${ARCH_SRC} ${CMAKE_CURRENT_SOURCE_DIR}/include/arch-internal.h) add_dependencies(diskscanlib scsicmd) # Build diskscan cli command add_executable(diskscan diskscan.c cli/cli.c cli/verbose.c progressbar/lib/progressbar.c) target_link_libraries(diskscan diskscanlib scsicmd m ${tinfo_LIBRARY} ${ZLIB_LIBRARIES} ${LIBS}) install(TARGETS diskscan RUNTIME DESTINATION bin) configure_file(Documentation/diskscan.1.in Documentation/diskscan.1) install(FILES ${CMAKE_CURRENT_BINARY_DIR}/Documentation/diskscan.1 DESTINATION share/man/man1 COMPONENT doc) diskscan-0.21/COPYING000066400000000000000000001045131456470715000143030ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. 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 them 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 prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. 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. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey 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; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. 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. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 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. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. 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 state 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program 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, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Lesser General Public License instead of this License. But first, please read . diskscan-0.21/DEVELOP.md000066400000000000000000000007641456470715000146730ustar00rootroot00000000000000# Developing ## Debug build To create a debug build you can tell cmake: cmake -DCMAKE_BUILD_TYPE=DEBUG . ## Updating Libraries Update libscsicmd: git subtree pull --squash --prefix libscsicmd https://github.com/baruch/libscsicmd master Update libprogressbar: git subtree pull --squash --prefix progressbar https://github.com/doches/progressbar master Update HdrHistogram: git subtree pull --squash --prefix hdrhistogram https://github.com/HdrHistogram/HdrHistogram_c master diskscan-0.21/Documentation/000077500000000000000000000000001456470715000160555ustar00rootroot00000000000000diskscan-0.21/Documentation/.gitignore000066400000000000000000000000051456470715000200400ustar00rootroot00000000000000/*.1 diskscan-0.21/Documentation/diskscan.1.in000066400000000000000000000054251456470715000203510ustar00rootroot00000000000000.TH DISKSCAN 1 2013-10-25 "DiskScan @PACKAGE_VERSION@" "User Commands" .ad l .nh .SH NAME diskscan - scan a disk for failed and near failure sectors .SH SYNOPSIS \fBdiskscan\fR [options...] \fIblock_device\fR .SH DESCRIPTION \fBdiskscan\fR is intended to check a disk and find any bad sectors already present and assess it for any possible sectors that are in the process of going bad. The operation is all read-only and can cause no direct damage to the data on the disk. .PP diskscan reads the entire block device and notes the time it took to read a block. When there is an error it is immediately noted and also when there is a higher latency to read a block. A histogram of the block latency times is also given to assess the health of the disk. .PP The output of diskscan will show any serious errors or very high latency and will also emit an histogram at the end of the run in the form: .RS +4n .nf .PP I: Validating path /dev/sdg I: Opened disk /dev/sdg I: Scanning disk /dev/sdg Access time histogram: 1: 0 10: 0 100: 0 500: 120 1000: 0 2000: 1 3000: 0 4000: 0 5000: 0 6000: 0 7000: 0 8000: 0 9000: 0 10000: 0 15000: 0 20000: 0 25000: 0 30000: 0 above that: 0 I: Closed disk /dev/sdg .fi .RE .PP This means that all I/Os in this case were between 100 and 600 msec and there were 120 chunks being read. Current these chunks are 1MB in size. .SH OPTIONS \fB-v\fR, \fB--verbose\fR display verbose information from the workings of the scan use multiple times for increased verbosity. .PP \fB-f\fR, \fB--fix\fR Attempt to fix areas that are nearing failure. This should only be attempted on an unmounted block device and never on an inuse filesystem or corruption is likely. .PP \fB-s \fR, \fB--scan \fR Scan mode can be either \fBseq\fR or \fBrandom\fR, random reduces the chance that the disk will be able spend time to recover data before we try to access a sector but the seeks add noise to the latency measurement. Sequential test is the default and random test is still experimental with regard to its usefulness. .PP \fB-e \fR, \fB--size \fR Set the size in which the scan will be done, this must be a multiple of the sector size which is normally 512 bytes. .PP \fB-o \fR, \fB--output \fR Set the output file that the scan will generate. This is a JSON file with the summary and details about the exceptional events found during the scan. .PP \fB-r \fR, \fB--raw-log \fR Set the output file for the raw log which logs everything done and seen during the scan. This is a rather large file but it can help get the finer details of the scan progress and the disk behavior during the scan. This is too a JSON file. .SH "SEE ALSO" \fBbadblocks\fR(1), \fBfsck\fR(1) .SH AUTHOR Baruch Even diskscan-0.21/README.md000066400000000000000000000043051456470715000145250ustar00rootroot00000000000000# DiskScan -- Scan HDD/SSD for failed and near failed sectors [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/baruch/diskscan?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) DiskScan is a Unix/Linux tool to scan a block device and check if there are unreadable sectors, in addition it uses read latency times as an assessment for a near failure as sectors that are problematic to read usually entail many retries. This can be used to assess the state of the disk and maybe decide on a replacement in advance to its imminent failure. The disk self test may or may not pick up on such clues depending on the disk vendor decision making logic. ## diskscan vs. badblocks badblocks is intended for a simple task, to find bad blocks in the media. diskscan is trying to say a lot more about the media, specifically it is trying not just to say where is a bad block but also what blocks are already deteriorated but still readable and also give information on the latency of reading each block which should help to give an overall assessment of the disk media. In essence badblocks looks for fatal issues already happening and diskscan is for upcoming issues that can be fixed. Also, badblocks is essentially obsolete in this day and age since the disks themselves will reallocate the data and there is no real need to map the bad blocks in the filesystem level anymore. # Supported Drives This tool is focused on SAS/SATA drives that work through the SCSI interface of the kernel. SD Cards and NVMe devices are not currently scannable with this tool. ## Build This project is using CMake, on Debian/Ubuntu it is as simple as: apt-get install cmake make libtinfo-dev libncurses5-dev zlib1g-dev python-yaml For RedHat/SuSe based distros you need to install ninja-build first and then: yum install compat-libtermcap libtermcap-devel cmake python-yaml zlib-devel A Makefile is provided to avoid learning the ninja commands and do the non-build stuff (install, etc.) To do the build: cmake . && make ## Install make install You can control the DESTDIR when building packages and PREFIX if /usr is not right. ## License diskscan is licensed under the GPL version 3 or later. diskscan-0.21/arch/000077500000000000000000000000001456470715000141615ustar00rootroot00000000000000diskscan-0.21/arch/arch-freebsd.c000066400000000000000000000045211456470715000166540ustar00rootroot00000000000000#include "arch.h" #include #include #include #include #include #include #include "arch-posix.c" #include int disk_dev_identify(disk_dev_t *dev, char *vendor, char *model, char *fw_rev, char *serial, bool *is_ata, unsigned char *ata_buf, unsigned *ata_buf_len) { (void)dev; strcpy(vendor, "UNKNOWN"); strcpy(model, "UNKNOWN"); strcpy(fw_rev, "UNKN"); strcpy(serial, "UNKNOWN"); *is_ata = 0; *ata_buf_len = 0; *ata_buf = 0; return 0; } int disk_dev_read_cap(disk_dev_t *dev, uint64_t *size_bytes, uint64_t *sector_size) { if (ioctl(dev->fd, DIOCGMEDIASIZE, size_bytes) < 0) { return -1; } if (ioctl(dev->fd, DIOCGSECTORSIZE, sector_size) < 0) { return -1; } return 0; } disk_mount_e disk_dev_mount_state(const char *path) { int num_mounts; struct statfs *mntbuf; disk_mount_e last_state; int i; num_mounts = getmntinfo(&mntbuf, MNT_WAIT); if (num_mounts == 0) { ERROR("Failed to get the mount information, errno=%d", errno); return DISK_MOUNTED_RW; } last_state = DISK_NOT_MOUNTED; for (i = 0; i < num_mounts; i++) { struct statfs *mnt = &mntbuf[i]; if (strncmp(path, mnt->f_mntfromname, strlen(path)) == 0) { disk_mount_e cur_state = DISK_NOT_MOUNTED; if (mnt->f_flags == MNT_RDONLY) cur_state = DISK_MOUNTED_RO; else cur_state = DISK_MOUNTED_RW; if (cur_state > last_state) last_state = cur_state; } } return last_state; } void mac_read(unsigned char *buf, int len) { struct ifreq ifr; struct ifconf ifc; char data[1024]; int success = 0; buf[0] = 0; int sock = socket(AF_INET, SOCK_DGRAM, 0); if (sock == -1) { return; }; ifc.ifc_len = sizeof(data); ifc.ifc_buf = data; if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) { /* handle error */ goto Exit; } struct ifreq* it = ifc.ifc_req; const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq)); for (; it != end; ++it) { strcpy(ifr.ifr_name, it->ifr_name); if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback if (ioctl(sock, SIOCGIFMAC, &ifr) == 0) { success = 1; break; } } } else { /* handle error */ } } if (success) { memcpy(buf, ifr.ifr_ifru.ifru_data, len >= 6 ? 6 : len); } else { memset(buf, 0, len); } Exit: close(sock); } diskscan-0.21/arch/arch-generic.c000066400000000000000000000013171456470715000166560ustar00rootroot00000000000000#include "arch.h" #include #include #include "arch-posix.c" int disk_dev_read_cap(disk_dev_t *dev, uint64_t *size_bytes, uint64_t *sector_size) { off_t end = lseek(dev->fd, 0, SEEK_END); if (end == (off_t)-1) return -1; *size_bytes = end; *sector_size = 512; return 0; } int disk_dev_identify(disk_dev_t *dev, char *vendor, char *model, char *fw_rev, char *serial, bool *is_ata, unsigned char *ata_buf, unsigned *ata_buf_len) { (void)dev; strcpy(vendor, "UNKNOWN"); strcpy(model, "UNKNOWN"); strcpy(fw_rev, "UNKN"); strcpy(serial, "UNKNOWN"); *is_ata = 0; *ata_buf_len = 0; *ata_buf = 0; return 0; } void mac_read(unsigned char *buf, int len) { (void)len; *buf = 0; } diskscan-0.21/arch/arch-linux.c000066400000000000000000000354351456470715000164110ustar00rootroot00000000000000#include "arch.h" #include "libscsicmd/include/scsicmd.h" #include "libscsicmd/include/ata.h" #include "libscsicmd/include/ata_parse.h" #include "verbose.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #define LONG_TIMEOUT (60*1000) // 1 minutes #define SHORT_TIMEOUT (5*1000) // 5 seconds static void strtrim(char *s) { char *t; // Skip initial spaces for (t = s; *t && isspace(*t); t++) ; if (t != s) { // Copy content to start while (*t && !isspace(*t)) { *s++ = *t++; } *s = 0; } else { while (*t && !isspace(*t)) t++; *t = 0; } } static enum result_error_e sense_to_error(sense_info_t *info) { // TODO: May need a more granular decision based on asc/ascq switch (info->sense_key) { case SENSE_KEY_NO_SENSE: return ERROR_NONE; case SENSE_KEY_RECOVERED_ERROR: return ERROR_CORRECTED; case SENSE_KEY_MEDIUM_ERROR: return ERROR_UNCORRECTED; case SENSE_KEY_UNIT_ATTENTION: case SENSE_KEY_NOT_READY: case SENSE_KEY_ABORTED_COMMAND: return ERROR_NEED_RETRY; case SENSE_KEY_HARDWARE_ERROR: case SENSE_KEY_ILLEGAL_REQUEST: case SENSE_KEY_DATA_PROTECT: case SENSE_KEY_BLANK_CHECK: case SENSE_KEY_VENDOR_SPECIFIC: case SENSE_KEY_COPY_ABORTED: case SENSE_KEY_RESERVED_C: case SENSE_KEY_VOLUME_OVERFLOW: case SENSE_KEY_MISCOMPARE: case SENSE_KEY_COMPLETED: return ERROR_FATAL; } ERROR("BUG: Cannot translate sense 0x%02X to error code", info->sense_key); return ERROR_UNKNOWN; } static const char *host_status_to_str(int host_status) { switch (host_status) { case 0x00: return "DID_OK: No error"; case 0x01: return "DID_NO_CONNECT: Couldn't connect before timeout period"; case 0x02: return "DID_BUS_BUSY: BUS stayed busy through time out period"; case 0x03: return "DID_TIME_OUT: TIMED OUT for other reason"; case 0x04: return "DID_BAD_TARGET: BAD target"; case 0x05: return "DID_ABORT: Told to abort for some other reason"; case 0x06: return "DID_PARITY: Parity error"; case 0x07: return "DID_ERROR: internal error"; case 0x08: return "DID_RESET: Reset by somebody"; case 0x09: return "DID_BAD_INTR: Got an interrupt we weren't expecting"; default: return "Unknown host status"; } } static const char *driver_status_low_to_str(int driver_status) { switch (driver_status) { case 0x00: return "DRIVER_OK: No error"; case 0x01: return "DRIVER_BUSY: not used"; case 0x02: return "DRIVER_SOFT: not used"; case 0x03: return "DRIVER_MEDIA: not used"; case 0x04: return "DRIVER_ERROR: internal driver error"; case 0x05: return "DRIVER_INVALID: finished (DID_BAD_TARGET or DID_ABORT)"; case 0x06: return "DRIVER_TIMEOUT: finished with timeout"; case 0x07: return "DRIVER_HARD: finished with fatal error"; case 0x08: return "DRIVER_SENSE: had sense information available"; default: return "Unknown driver status"; } } static const char *driver_status_high_to_str(int driver_status) { switch (driver_status) { case 0: return "No suggestion"; case 0x10: return "SUGGEST_RETRY: retry the SCSI request"; case 0x20: return "SUGGEST_ABORT: abort the request"; case 0x30: return "SUGGEST_REMAP: remap the block (not yet implemented)"; case 0x40: return "SUGGEST_DIE: let the kernel panic"; case 0x80: return "SUGGEST_SENSE: get sense information from the device"; case 0xff: return "SUGGEST_IS_OK: nothing to be done"; default: return "Unknown suggestion"; } } static const char *status_code_to_str(int status) { switch (status) { case 0x00: return "GOOD"; case 0x01: return "CHECK_CONDITION"; case 0x02: return "CONDITION_GOOD"; case 0x04: return "BUSY"; case 0x08: return "INTERMEDIATE_GOOD"; case 0x0a: return "INTERMEDIATE_C_GOOD"; case 0x0c: return "RESERVATION_CONFLICT"; default: return "Unknown status"; } } static const char *driver_status_to_str(int driver_status) { static char buf[256]; snprintf(buf, sizeof(buf), "%s %s", driver_status_low_to_str(driver_status & 0x0F), driver_status_high_to_str(driver_status & 0xF0)); return buf; } static int sg_ioctl(int fd, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_len, int dxfer_direction, unsigned timeout, unsigned char *sense, unsigned sense_len, unsigned *buf_read, unsigned *sense_read, io_result_t *io_res) { sg_io_hdr_t hdr; int ret; memset(&hdr, 0, sizeof(hdr)); memset(io_res, 0, sizeof(*io_res)); *sense_read = 0; *buf_read = 0; hdr.interface_id = 'S'; hdr.dxfer_direction = dxfer_direction; hdr.cmd_len = cdb_len; hdr.mx_sb_len = sense_len; hdr.dxfer_len = buf_len; hdr.dxferp = buf; hdr.cmdp = cdb; hdr.sbp = sense; hdr.timeout = timeout; /* timeout in milliseconds */ hdr.flags = SG_FLAG_LUN_INHIBIT; hdr.pack_id = 0; hdr.usr_ptr = 0; ret = ioctl(fd, SG_IO, &hdr); if (ret < 0) { ERROR("Failed to issue ioctl to device errno=%d: %s", errno, strerror(errno)); io_res->error = ERROR_FATAL; io_res->data = DATA_NONE; return -1; } #if 0 if (hdr.status || hdr.driver_status || hdr.msg_status || hdr.host_status || hdr.sb_len_wr) { printf("status: %d %s\n", hdr.status, status_code_to_str(hdr.status)); printf("masked status: %d\n", hdr.masked_status); printf("driver status: %d %s\n", hdr.driver_status, driver_status_to_str(hdr.driver_status)); printf("msg status: %d\n", hdr.msg_status); printf("host status: %d = %s\n", hdr.host_status, host_status_to_str(hdr.host_status)); printf("sense len: %d\n", hdr.sb_len_wr); } #endif *buf_read = hdr.dxfer_len - hdr.resid; if (*buf_read == buf_len) io_res->data = DATA_FULL; else if (*buf_read == 0) io_res->data = DATA_NONE; else io_res->data = DATA_PARTIAL; if (hdr.sb_len_wr) { memcpy(io_res->sense, sense, hdr.sb_len_wr); io_res->sense_len = hdr.sb_len_wr; *sense_read = hdr.sb_len_wr; // Error with sense, parse the sense if (scsi_parse_sense(sense, hdr.sb_len_wr, &io_res->info)) { io_res->error = sense_to_error(&io_res->info); } else { // Parsing of the sense failed, assume the worst io_res->error = ERROR_UNKNOWN; } return 0; } if (hdr.status != 0) { // No sense but we have an error, consider it fatal if no data returned ERROR("IO failed with no sense: status=%d (%s) mask=%d driver=%d (%s) msg=%d host=%d (%s)", hdr.status, status_code_to_str(hdr.status), hdr.masked_status, hdr.driver_status, driver_status_to_str(hdr.driver_status), hdr.msg_status, hdr.host_status, host_status_to_str(hdr.host_status)); if (*buf_read == 0) io_res->error = ERROR_UNKNOWN; return 0; } io_res->error = ERROR_NONE; return 0; } static disk_mount_e mount_point_check(struct mntent *mnt) { char *next = mnt->mnt_opts; char *opt; /* Device is mounted, check it */ while ((opt = strtok(next, ", \t\r\n")) != NULL) { next = NULL; // continue scanning for this string if (strcmp(opt, "rw") == 0) return DISK_MOUNTED_RW; } return DISK_MOUNTED_RO; } disk_mount_e disk_dev_mount_state(const char *path) { struct stat dev_st_buf; struct stat st_buf; FILE *f = NULL; struct mntent *mnt; disk_mount_e state = DISK_MOUNTED_RW; // assume the worst f = setmntent("/proc/mounts", "r"); if (f == NULL) { ERROR("Failed to open /proc/mounts to know the state, errno=%d", errno); goto Exit; } if (stat(path, &dev_st_buf) != 0) { ERROR("Failed to stat the path %s, errno=%d", path, errno); goto Exit; } if (!S_ISBLK(dev_st_buf.st_mode)) { ERROR("Device %s is not a block device", path); goto Exit; // We only want block devices } // From here we assume the disk is not mounted state = DISK_NOT_MOUNTED; while ((mnt = getmntent(f)) != NULL) { disk_mount_e cur_state = DISK_NOT_MOUNTED; /* Ignore non-full-path entries */ if (mnt->mnt_fsname[0] != '/') continue; /* Check for a name prefix match, we may check a full block device and a partition is mounted */ if (strncmp(path, mnt->mnt_fsname, strlen(path)) == 0) { cur_state = mount_point_check(mnt); if (cur_state > state) state = cur_state; continue; } /* Check for an underlying device match (name may have changed in between actions) */ if (stat(mnt->mnt_fsname, &st_buf) == 0) { if (!S_ISBLK(st_buf.st_mode)) continue; if (dev_st_buf.st_rdev == st_buf.st_rdev) { cur_state = mount_point_check(mnt); if (cur_state > state) state = cur_state; } } } Exit: if (f) endmntent(f); return state; } bool disk_dev_open(disk_dev_t *dev, const char *path) { dev->fd = open(path, O_RDWR|O_DIRECT); return dev->fd >= 0; } void disk_dev_close(disk_dev_t *dev) { close(dev->fd); dev->fd = -1; } void disk_dev_cdb_out(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, unsigned char *sense, unsigned sense_size, unsigned *sense_read, io_result_t *io_res) { sg_ioctl(dev->fd, cdb, cdb_len, buf, buf_size, SG_DXFER_TO_DEV, LONG_TIMEOUT, sense, sense_size, buf_read, sense_read, io_res); } void disk_dev_cdb_in(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, unsigned char *sense, unsigned sense_size, unsigned *sense_read, io_result_t *io_res) { sg_ioctl(dev->fd, cdb, cdb_len, buf, buf_size, SG_DXFER_FROM_DEV, LONG_TIMEOUT, sense, sense_size, buf_read, sense_read, io_res); } ssize_t disk_dev_read(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res) { unsigned char cdb[32]; unsigned char sense[128]; int cdb_len; unsigned buf_read = 0; unsigned sense_read = 0; int ret; memset(buf, 0, len_bytes); memset(io_res, 0, sizeof(*io_res)); cdb_len = cdb_read_10(cdb, false, offset_bytes / dev->sector_size, len_bytes / dev->sector_size); ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, len_bytes, SG_DXFER_FROM_DEV, LONG_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, io_res); if (ret < 0) { return -1; } if (buf_read < len_bytes && sense_read > 0) { VERBOSE("not all read: requested=%u read=%u sense=%u", len_bytes, buf_read, sense_read); return -1; } return buf_read; } ssize_t disk_dev_write(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res) { unsigned char cdb[32]; unsigned char sense[128]; int cdb_len; unsigned buf_read = 0; unsigned sense_read = 0; int ret; memset(buf, 0, len_bytes); memset(io_res, 0, sizeof(*io_res)); cdb_len = cdb_write_10(cdb, false, offset_bytes / dev->sector_size, len_bytes / dev->sector_size); ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, len_bytes, SG_DXFER_TO_DEV, LONG_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, io_res); if (ret < 0) { return -1; } if (buf_read < len_bytes && sense_read > 0) { VERBOSE("not all read: requested=%u read=%u sense=%u", len_bytes, buf_read, sense_read); return -1; } return buf_read; } int disk_dev_read_cap(disk_dev_t *dev, uint64_t *size_bytes, uint64_t *sector_size) { unsigned char cdb[32]; unsigned char buf[512]; unsigned char sense[128]; int cdb_len; unsigned buf_read = 0; unsigned sense_read = 0; int ret; io_result_t io_res; memset(buf, 0, sizeof(buf)); cdb_len = cdb_read_capacity_10(cdb); ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, SHORT_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, &io_res); if (ret < 0) return -1; uint32_t size_bytes_32; uint32_t block_size; if (!parse_read_capacity_10(buf, buf_read, &size_bytes_32, &block_size)) return -1; if (sense_read > 0) // TODO: Parse to see if real error or something we can ignore return -1; if (size_bytes_32 < 0xFFFFFFFF) { *size_bytes = (uint64_t)size_bytes_32 * 512; dev->sector_size = *sector_size = block_size; return 0; } // disk size is too large for READ CAPACITY 10, need to use READ CAPACITY 16 cdb_len = cdb_read_capacity_16(cdb, sizeof(buf)); ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, SHORT_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, &io_res); if (ret < 0) return -1; if (sense_read > 0) // TODO: Parse to see if real error or something we can ignore return -1; if (!parse_read_capacity_16_simple(buf, buf_read, size_bytes, &block_size)) return -1; *size_bytes *= 512; dev->sector_size = *sector_size = block_size; return 0; } int disk_dev_identify(disk_dev_t *dev, char *vendor, char *model, char *fw_rev, char *serial, bool *is_ata, unsigned char *ata_buf, unsigned *ata_buf_len) { unsigned char cdb[32]; unsigned char buf[512]; unsigned char sense[128]; int cdb_len; unsigned buf_read = 0; unsigned sense_read = 0; int ret; io_result_t io_res; *is_ata = false; *ata_buf_len = 0; memset(buf, 0, sizeof(buf)); cdb_len = cdb_inquiry_simple(cdb, 96); ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, SHORT_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, &io_res); if (ret < 0) return -1; int device_type; if (!parse_inquiry(buf, buf_read, &device_type, vendor, model, fw_rev, serial)) { INFO("Failed to parse the inquiry data"); return -1; } strtrim(vendor); strtrim(model); strtrim(fw_rev); strtrim(serial); // If the vendor doesn't start with ATA it is a proper SCSI interface if (strncmp(vendor, "ATA", 3) != 0) return 0; *is_ata = true; // For an ATA disk we need to get the proper ATA IDENTIFY response memset(buf, 0, sizeof(buf)); cdb_len = cdb_ata_identify(cdb); ret = sg_ioctl(dev->fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV, SHORT_TIMEOUT, sense, sizeof(sense), &buf_read, &sense_read, &io_res); if (ret < 0) return -1; ata_get_ata_identify_model(buf, vendor); strtrim(vendor); strcpy(model, vendor + strlen(vendor) + 1); strtrim(model); ata_get_ata_identify_fw_rev(buf, fw_rev); strtrim(fw_rev); ata_get_ata_identify_serial_number(buf, serial); strtrim(serial); memcpy(ata_buf, buf, buf_read); *ata_buf_len = buf_read; return 0; } void mac_read(unsigned char *buf, int len) { struct ifreq ifr; struct ifconf ifc; char data[1024]; int success = 0; buf[0] = 0; int sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_IP); if (sock == -1) { return; }; ifc.ifc_len = sizeof(data); ifc.ifc_buf = data; if (ioctl(sock, SIOCGIFCONF, &ifc) == -1) { /* handle error */ goto Exit; } struct ifreq* it = ifc.ifc_req; const struct ifreq* const end = it + (ifc.ifc_len / sizeof(struct ifreq)); for (; it != end; ++it) { strcpy(ifr.ifr_name, it->ifr_name); if (ioctl(sock, SIOCGIFFLAGS, &ifr) == 0) { if (! (ifr.ifr_flags & IFF_LOOPBACK)) { // don't count loopback if (ioctl(sock, SIOCGIFHWADDR, &ifr) == 0) { success = 1; break; } } } else { /* handle error */ } } if (success) { memcpy(buf, ifr.ifr_hwaddr.sa_data, len >= 6 ? 6 : len); } else { memset(buf, 0, len); } Exit: close(sock); } diskscan-0.21/arch/arch-linux.h000066400000000000000000000001741456470715000164060ustar00rootroot00000000000000#ifndef ARCH_INTERNAL_LINUX_H #define ARCH_INTERNAL_LINUX_H struct disk_dev_t { int fd; uint32_t sector_size; }; #endif diskscan-0.21/arch/arch-posix.c000066400000000000000000000047061456470715000164110ustar00rootroot00000000000000#include #include #include #include #include #include #include #include "verbose.h" #include "arch.h" bool disk_dev_open(disk_dev_t *dev, const char *path) { dev->fd = open(path, O_RDWR|O_DIRECT); if (dev->fd < 0) { INFO("Failed to open device %s with write permission, retrying without", path); dev->fd = open(path, O_RDONLY|O_DIRECT); } return dev->fd >= 0; } void disk_dev_close(disk_dev_t *dev) { close(dev->fd); dev->fd = -1; } ssize_t disk_dev_read(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res) { ssize_t ret = pread(dev->fd, buf, len_bytes, offset_bytes); if (ret == len_bytes) { io_res->data = DATA_FULL; io_res->error = ERROR_NONE; return ret; } else if (ret > 0) { io_res->data = DATA_PARTIAL; io_res->error = ERROR_NONE; return ret; } else if (ret == 0) { io_res->data = DATA_NONE; io_res->error = ERROR_NONE; return ret; } else { // ret < 0, i.e. error INFO("Error reading from disk, offset=%lu len=%u errno=%d (%s)", offset_bytes, len_bytes, errno, strerror(errno)); io_res->data = DATA_NONE; io_res->error = ERROR_UNCORRECTED; io_res->sense_len = 0; memset(&io_res->info, 0, sizeof(io_res->info)); return -1; } //TODO: Handle EINTR with a retry } ssize_t disk_dev_write(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res) { ssize_t ret = pwrite(dev->fd, buf, len_bytes, offset_bytes); if (ret == len_bytes) { io_res->data = DATA_FULL; io_res->error = ERROR_NONE; return ret; } else if (ret > 0) { io_res->data = DATA_PARTIAL; io_res->error = ERROR_NONE; return ret; } else if (ret == 0) { io_res->data = DATA_NONE; io_res->error = ERROR_NONE; return ret; } else { // ret < 0, i.e. error io_res->data = DATA_NONE; io_res->error = ERROR_UNCORRECTED; io_res->sense_len = 0; memset(&io_res->info, 0, sizeof(io_res->info)); return -1; } //TODO: Handle EINTR with a retry } void disk_dev_cdb_in(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, unsigned char *sense, unsigned sense_size, unsigned *sense_read, io_result_t *io_res) { (void)sense_size; (void)sense; (void)buf_size; (void)buf; (void)cdb_len; (void)cdb; (void)dev; *sense_read = 0; *buf_read = 0; memset(&io_res, 0, sizeof(*io_res)); io_res->data = DATA_NONE; io_res->error = ERROR_NONE; } diskscan-0.21/arch/arch-posix.h000066400000000000000000000001451456470715000164070ustar00rootroot00000000000000#ifndef ARCH_INTERNAL_POSIX_H #define ARCH_INTERNAL_POSIX_H struct disk_dev_t { int fd; }; #endif diskscan-0.21/cli/000077500000000000000000000000001456470715000140135ustar00rootroot00000000000000diskscan-0.21/cli/cli.c000066400000000000000000000205351456470715000147330ustar00rootroot00000000000000/* * Copyright 2013 Baruch Even * * This file is part of DiskScan. * * DiskScan is free software: 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 3 of the License, or * (at your option) any later version. * * DiskScan is distributed in the hope that 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 DiskScan. If not, see . * */ #include "verbose.h" #include "diskscan.h" #include "compiler.h" #include "cli.h" #include "progressbar/include/progressbar.h" #include "hdrhistogram/src/hdr_histogram.h" #include #include #include #include #include #include #include #include static disk_t disk; static progressbar *bar; typedef struct options_t options_t; struct options_t { char *disk_path; int verbose; int fix; enum scan_mode mode; unsigned scan_size; char *data_log_name; char *data_log_raw_name; disk_mount_e allowed_mount; }; static void print_header(void) { printf("diskscan version %s\n\n", VERSION); VERBOSE("Verbosity set"); VVERBOSE("High verbosity set"); VVVERBOSE("Very high verbosity set"); } static int usage(void) { printf("diskscan version %s\n\n", VERSION); printf("diskscan [options] /dev/sd\n"); printf("Options:\n"); printf(" -v, --verbose - Increase verbosity, multiple uses for higher levels\n"); printf(" -f, --fix - Attempt to fix near failures, nothing can be done for unreadable sectors\n"); printf(" -s, --scan - Scan in order (seq, random)\n"); printf(" -e, --size - Scan size (default to 64K, must be multiple of 512)\n"); printf(" -o, --output - Output file (json)\n"); printf(" -r, --raw-log - Raw log of all scan results (json)\n"); printf(" --force-mounted - Allow checking a read-only mounted disk\n"); printf(" --force-mounted-rw - Allow checking a read-write mounted disk\n"); printf("\n"); return 1; } void report_progress(disk_t * UNUSED(disk), int progress_part, int progress_full) { if (bar == NULL) bar = progressbar_new("Disk scan", progress_full); progressbar_update(bar, progress_part); } void report_scan_success(disk_t *UNUSED(disk), uint64_t UNUSED(offset_bytes), uint64_t UNUSED(data_size), uint64_t UNUSED(time)) { } void report_scan_error(disk_t *UNUSED(disk), uint64_t UNUSED(offset_bytes), uint64_t UNUSED(data_size), uint64_t UNUSED(time)) { } static void print_latency(latency_t *latency_graph, unsigned latency_graph_len) { unsigned i; const uint32_t height = 30; // number of lines to fill const uint32_t min_val = 0; uint32_t max_val = 1; for (i = 0; i < latency_graph_len; i++) { if (max_val < latency_graph[i].latency_max_msec) max_val = latency_graph[i].latency_max_msec; } uint32_t height_interval = (max_val - min_val + 1) / (height - 3); if (height_interval == 0) height_interval = 1; else if (height_interval > 10000) height_interval = 10000; uint32_t j; for (j = height; j > 0; j--) { if (j % 5 == 0) printf("%5u | ", j * height_interval); else printf(" | "); for (i = 0; i < latency_graph_len; i++) { uint32_t max_height = latency_graph[i].latency_max_msec / height_interval + 1; uint32_t med_height = latency_graph[i].latency_median_msec / height_interval + 1; uint32_t min_height = latency_graph[i].latency_min_msec / height_interval + 1; if (max_height == med_height) { max_height++; } if (med_height == min_height) { med_height++; if (max_height == med_height) max_height++; } if (max_height != j && med_height != j && min_height != j) { printf(" "); continue; } if (max_height == j) printf("^"); else if (med_height == j) printf("*"); else printf("_"); } printf("\n"); } printf(" +-"); for (i = 0; i < latency_graph_len; i++) { printf("-"); } printf("\n"); } void report_scan_done(disk_t *pdisk) { progressbar_finish(bar); printf("\nAccess time histogram:\n"); hdr_percentiles_print(pdisk->histogram, stdout, 5, 1000.0, CLASSIC); // Print msecs printf("\nLatency graph:\n"); print_latency(pdisk->latency_graph, pdisk->latency_graph_len); printf("\nConclusion: %s\n", conclusion_to_str(pdisk->conclusion)); } static unsigned str_to_scan_size(const char *str) { char *endptr; long int val; errno = 0; val = strtol(str, &endptr, 0); if (errno != 0 || val <= 0) { ERROR("Failed to parse the value (%s) to a number", str); return 0; } if (*endptr != 0) { unsigned factor = 1; if (strcmp(endptr, "b") == 0 || strcmp(endptr, "B") == 0) factor = 1; else if (strcmp(endptr, "k") == 0 || strcmp(endptr, "K") == 0) factor = 1024; else if (strcmp(endptr, "m") == 0 || strcmp(endptr, "M") == 0) factor = 1024*1024; else { ERROR("Unknown suffix '%s': B, K, and M are accepted", endptr); return 0; } val *= factor; } unsigned retval = (unsigned)val; if (retval > 32*1024*1024) { ERROR("Maximum transfer size is 32MB, cannot handle more than that for now."); return 0; } return (unsigned)val; } static int parse_args(int argc, char **argv, options_t *opts) { int c; int unknown = 0; static int allowed_mount = DISK_NOT_MOUNTED; opts->scan_size = 64*1024; while (1) { int option_index = 0; static struct option long_options[] = { {"verbose", no_argument, 0, 'v'}, {"fix", no_argument, 0, 'f'}, {"scan", required_argument, 0, 's'}, {"size", required_argument, 0, 'e'}, {"raw-log", required_argument, 0, 'r'}, {"output", required_argument, 0, 'o'}, {"force-mounted", no_argument, &allowed_mount, DISK_MOUNTED_RO}, {"force-mounted-rw", no_argument, &allowed_mount, DISK_MOUNTED_RW}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "vfs:e:o:r:", long_options, &option_index); if (c == -1) break; switch (c) { case 0: break; case 'v': opts->verbose++; break; case 'f': opts->fix = 1; break; case 's': opts->mode = str_to_scan_mode(optarg); if (opts->mode == SCAN_MODE_UNKNOWN) { opts->mode = SCAN_MODE_SEQ; printf("Unknown scan mode %s given, using sequential\n", optarg); } break; case 'e': opts->scan_size = str_to_scan_size(optarg); break; case 'o': opts->data_log_name = optarg; break; case 'r': opts->data_log_raw_name = optarg; break; default: unknown = 1; break; } } if (optind == argc) { printf("No disk path provided to scan!\n"); return usage(); } if (optind < argc - 1) { printf("Too many disk paths provided to scan, can only scan one disk!\n"); return usage(); } if (unknown) { printf("Unknown option provided\n"); return usage(); } if (opts->scan_size == 0) { printf("Scan size is invalid, must be a positive number\n"); return usage(); } opts->disk_path = argv[optind]; opts->allowed_mount = allowed_mount; return 0; } /* static int print_disk_info(disk_t *UNUSED(disk)) { return 0; } */ static void diskscan_cli_signal(int UNUSED(signal)) { disk_scan_stop(&disk); } static void setup_signals(void) { struct sigaction act = { .sa_handler = diskscan_cli_signal, .sa_flags = SA_RESTART, }; sigaction(SIGINT, &act, NULL); sigaction(SIGTERM, &act, NULL); } int diskscan_cli(int argc, char **argv) { int ret; options_t opts; memset(&opts, 0, sizeof(opts)); opts.mode = SCAN_MODE_SEQ; opts.allowed_mount = DISK_NOT_MOUNTED; if (parse_args(argc, argv, &opts)) return 1; verbose = opts.verbose; print_header(); setup_signals(); if (disk_open(&disk, opts.disk_path, opts.fix, 70, opts.allowed_mount)) return 1; /* if (print_disk_info(&disk)) return 1; */ if (opts.data_log_raw_name) data_log_raw_start(&disk.data_raw, opts.data_log_raw_name, &disk); if (opts.data_log_name) data_log_start(&disk.data_log, opts.data_log_name, &disk); ret = 0; if (disk_scan(&disk, opts.mode, opts.scan_size)) ret = 1; if (opts.data_log_raw_name) data_log_raw_end(&disk.data_raw); if (opts.data_log_name) data_log_end(&disk.data_log, &disk); disk_close(&disk); return ret; } diskscan-0.21/cli/verbose.c000066400000000000000000000017541456470715000156330ustar00rootroot00000000000000/* * Copyright 2013 Baruch Even * * This file is part of DiskScan. * * DiskScan is free software: 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 3 of the License, or * (at your option) any later version. * * DiskScan is distributed in the hope that 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 DiskScan. If not, see . * */ #include "verbose.h" #include #include int verbose_extra_newline; void verbose_out(const char *fmt, ...) { va_list ap; if (verbose_extra_newline) printf("\n"); va_start(ap, fmt); vprintf(fmt, ap); va_end(ap); printf("\n"); } diskscan-0.21/diskscan.c000066400000000000000000000015041456470715000152070ustar00rootroot00000000000000/* * Copyright 2013 Baruch Even * * This file is part of DiskScan. * * DiskScan is free software: 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 3 of the License, or * (at your option) any later version. * * DiskScan is distributed in the hope that 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 DiskScan. If not, see . * */ #include "cli.h" int main(int argc, char **argv) { return diskscan_cli(argc, argv); } diskscan-0.21/distclean.sh000077500000000000000000000015211456470715000155500ustar00rootroot00000000000000#!/bin/sh # distclean.sh for diskscan # Copyright 2015 Joao Eriberto Mota Filho # v2015111402 # This file can used under GPL-3+ license or BSD-3-Clause. PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin PREFIX="." # Files and directories to remove OBJS=" CMakeFiles/ \ Makefile \ CMakeCache.txt \ Documentation/diskscan.1 \ cmake_install.cmake \ install_manifest.txt \ libscsicmd/src/CMakeFiles/ \ libscsicmd/src/Makefile \ libscsicmd/src/cmake_install.cmake \ tags" # Main procedures remove_files () { if [ -e "$PREFIX/$TARGET" ]; then echo "Removing $PREFIX/$TARGET" rm -rf "${PREFIX:?}/$TARGET" else echo "$PREFIX/$TARGET NOT FOUND." fi } # Distclean echo "DOING DISTCLEAN..." for TARGET in $OBJS do remove_files done echo "DONE." echo diskscan-0.21/hdrhistogram/000077500000000000000000000000001456470715000157375ustar00rootroot00000000000000diskscan-0.21/hdrhistogram/.gitignore000066400000000000000000000013321456470715000177260ustar00rootroot00000000000000target .idea out gh-pages HdrHistogram.iml .classpath .project .settings release.properties /bin alltests format_example *.a *.iml .sconsign.dblite *.o *.os .DS_Store build CMakeCache.txt CMakeFiles/ CPackConfig.cmake CPackSourceConfig.cmake CTestTestfile.cmake Makefile Testing/ cmake_install.cmake examples/CMakeFiles/ examples/CTestTestfile.cmake examples/Makefile examples/cmake_install.cmake examples/hdr_decoder examples/hiccup src/CMakeFiles/ src/CTestTestfile.cmake src/Makefile src/cmake_install.cmake src/libhdr_histogram.so test/CMakeFiles/ test/CTestTestfile.cmake test/Makefile test/cmake_install.cmake test/hdr_dbl_histogram_test test/hdr_histogram_log_test test/hdr_histogram_test test/perftest .gdb_history debug diskscan-0.21/hdrhistogram/CMakeLists.txt000066400000000000000000000012051456470715000204750ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) if("${CMAKE_VERSION}" VERSION_GREATER 3.0.0) cmake_policy(SET CMP0042 NEW) endif() project("hdr_histogram") ENABLE_TESTING() if(UNIX) set(CMAKE_C_FLAGS "-Wall -Wno-unknown-pragmas -Wextra -Wshadow -Winit-self -Wmissing-prototypes -D_GNU_SOURCE") set(CMAKE_C_FLAGS_DEBUG "-O0 -g") set(CMAKE_C_FLAGS_RELEASE "-O3 -g") endif() include_directories("${CMAKE_SOURCE_DIR}/src") add_subdirectory("${CMAKE_SOURCE_DIR}/src") add_subdirectory("${CMAKE_SOURCE_DIR}/test") add_subdirectory("${CMAKE_SOURCE_DIR}/examples") SET(CPACK_GENERATOR "TGZ") SET(CPACK_PACKAGE_VERSION "0.9.1") INCLUDE(CPack) diskscan-0.21/hdrhistogram/COPYING.txt000066400000000000000000000156101456470715000176130ustar00rootroot00000000000000Creative Commons Legal Code CC0 1.0 Universal CREATIVE COMMONS CORPORATION IS NOT A LAW FIRM AND DOES NOT PROVIDE LEGAL SERVICES. DISTRIBUTION OF THIS DOCUMENT DOES NOT CREATE AN ATTORNEY-CLIENT RELATIONSHIP. CREATIVE COMMONS PROVIDES THIS INFORMATION ON AN "AS-IS" BASIS. CREATIVE COMMONS MAKES NO WARRANTIES REGARDING THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER, AND DISCLAIMS LIABILITY FOR DAMAGES RESULTING FROM THE USE OF THIS DOCUMENT OR THE INFORMATION OR WORKS PROVIDED HEREUNDER. Statement of Purpose The laws of most jurisdictions throughout the world automatically confer exclusive Copyright and Related Rights (defined below) upon the creator and subsequent owner(s) (each and all, an "owner") of an original work of authorship and/or a database (each, a "Work"). Certain owners wish to permanently relinquish those rights to a Work for the purpose of contributing to a commons of creative, cultural and scientific works ("Commons") that the public can reliably and without fear of later claims of infringement build upon, modify, incorporate in other works, reuse and redistribute as freely as possible in any form whatsoever and for any purposes, including without limitation commercial purposes. These owners may contribute to the Commons to promote the ideal of a free culture and the further production of creative, cultural and scientific works, or to gain reputation or greater distribution for their Work in part through the use and efforts of others. For these and/or other purposes and motivations, and without any expectation of additional consideration or compensation, the person associating CC0 with a Work (the "Affirmer"), to the extent that he or she is an owner of Copyright and Related Rights in the Work, voluntarily elects to apply CC0 to the Work and publicly distribute the Work under its terms, with knowledge of his or her Copyright and Related Rights in the Work and the meaning and intended legal effect of CC0 on those rights. 1. Copyright and Related Rights. A Work made available under CC0 may be protected by copyright and related or neighboring rights ("Copyright and Related Rights"). Copyright and Related Rights include, but are not limited to, the following: i. the right to reproduce, adapt, distribute, perform, display, communicate, and translate a Work; ii. moral rights retained by the original author(s) and/or performer(s); iii. publicity and privacy rights pertaining to a person's image or likeness depicted in a Work; iv. rights protecting against unfair competition in regards to a Work, subject to the limitations in paragraph 4(a), below; v. rights protecting the extraction, dissemination, use and reuse of data in a Work; vi. database rights (such as those arising under Directive 96/9/EC of the European Parliament and of the Council of 11 March 1996 on the legal protection of databases, and under any national implementation thereof, including any amended or successor version of such directive); and vii. other similar, equivalent or corresponding rights throughout the world based on applicable law or treaty, and any national implementations thereof. 2. Waiver. To the greatest extent permitted by, but not in contravention of, applicable law, Affirmer hereby overtly, fully, permanently, irrevocably and unconditionally waives, abandons, and surrenders all of Affirmer's Copyright and Related Rights and associated claims and causes of action, whether now known or unknown (including existing as well as future claims and causes of action), in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "Waiver"). Affirmer makes the Waiver for the benefit of each member of the public at large and to the detriment of Affirmer's heirs and successors, fully intending that such Waiver shall not be subject to revocation, rescission, cancellation, termination, or any other legal or equitable action to disrupt the quiet enjoyment of the Work by the public as contemplated by Affirmer's express Statement of Purpose. 3. Public License Fallback. Should any part of the Waiver for any reason be judged legally invalid or ineffective under applicable law, then the Waiver shall be preserved to the maximum extent permitted taking into account Affirmer's express Statement of Purpose. In addition, to the extent the Waiver is so judged Affirmer hereby grants to each affected person a royalty-free, non transferable, non sublicensable, non exclusive, irrevocable and unconditional license to exercise Affirmer's Copyright and Related Rights in the Work (i) in all territories worldwide, (ii) for the maximum duration provided by applicable law or treaty (including future time extensions), (iii) in any current or future medium and for any number of copies, and (iv) for any purpose whatsoever, including without limitation commercial, advertising or promotional purposes (the "License"). The License shall be deemed effective as of the date CC0 was applied by Affirmer to the Work. Should any part of the License for any reason be judged legally invalid or ineffective under applicable law, such partial invalidity or ineffectiveness shall not invalidate the remainder of the License, and in such case Affirmer hereby affirms that he or she will not (i) exercise any of his or her remaining Copyright and Related Rights in the Work or (ii) assert any associated claims and causes of action with respect to the Work, in either case contrary to Affirmer's express Statement of Purpose. 4. Limitations and Disclaimers. a. No trademark or patent rights held by Affirmer are waived, abandoned, surrendered, licensed or otherwise affected by this document. b. Affirmer offers the Work as-is and makes no representations or warranties of any kind concerning the Work, express, implied, statutory or otherwise, including without limitation warranties of title, merchantability, fitness for a particular purpose, non infringement, or the absence of latent or other defects, accuracy, or the present or absence of errors, whether or not discoverable, all to the greatest extent permissible under applicable law. c. Affirmer disclaims responsibility for clearing rights of other persons that may apply to the Work or any use thereof, including without limitation any person's Copyright and Related Rights in the Work. Further, Affirmer disclaims responsibility for obtaining any necessary consents, permissions or other rights required for any use of the Work. d. Affirmer understands and acknowledges that Creative Commons is not a party to this document and has no duty or obligation with respect to this CC0 or use of the Work. diskscan-0.21/hdrhistogram/LICENSE.txt000066400000000000000000000041611456470715000175640ustar00rootroot00000000000000The code in this repository code was Written by Gil Tene, Michael Barker, and Matt Warren, and released to the public domain, as explained at http://creativecommons.org/publicdomain/zero/1.0/ For users of this code who wish to consume it under the "BSD" license rather than under the public domain or CC0 contribution text mentioned above, the code found under this directory is *also* provided under the following license (commonly referred to as the BSD 2-Clause License). This license does not detract from the above stated release of the code into the public domain, and simply represents an additional license granted by the Author. ----------------------------------------------------------------------------- ** Beginning of "BSD 2-Clause License" text. ** Copyright (c) 2012, 2013, 2014 Gil Tene Copyright (c) 2014 Michael Barker Copyright (c) 2014 Matt Warren 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. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. diskscan-0.21/hdrhistogram/README.md000066400000000000000000000041771456470715000172270ustar00rootroot00000000000000HdrHistogram_c: 'C' port of High Dynamic Range (HDR) Histogram HdrHistogram ---------------------------------------------- [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/HdrHistogram/HdrHistogram?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) This port contains a subset of the functionality supported by the Java implementation. The current supported features are: * Standard histogram with 64 bit counts (32/16 bit counts not supported) * All iterator types (all values, recorded, percentiles, linear, logarithmic) * Histogram serialisation (encoding version 1.2, decoding 1.0-1.2) * Reader/writer phaser and interval recorder Features not supported, but planned * Auto-resizing of histograms Features unlikely to be implemented * Double histograms * Atomic/Concurrent histograms * 16/32 bit histograms # Simple Tutorial ## Recording values ```C #include struct hdr_histogram* histogram; // Initialise the histogram hdr_init( 1, // Minimum value INT64_C(3600000000), // Maximum value 3, // Number of significant figures &histogram) // Pointer to initialise // Record value hdr_record_value( histogram, // Histogram to record to value) // Value to record // Record value n times hdr_record_value( histogram, // Histogram to record to value, // Value to record 10) // Record value 10 times // Record value with correction for co-ordinated omission. hdr_record_corrected_value( histogram, // Histogram to record to value, // Value to record 1000) // Record with expected interval of 1000. // Print out the values of the histogram hdr_percentiles_print( histogram, stdout, // File to write to 5, // Granularity of printed values 1.0, // Multiplier for results CLASSIC); // Format CLASSIC/CSV supported. ``` ## More examples For more detailed examples of recording and logging results look at the [hdr_decoder](examples/hdr_decoder.c) and [hiccup](examples/hiccup.c) examples. You can run hiccup and decoder and pipe the results of one into the other. ``` $ ./examples/hiccup | ./examples/hdr_decoder ```diskscan-0.21/hdrhistogram/examples/000077500000000000000000000000001456470715000175555ustar00rootroot00000000000000diskscan-0.21/hdrhistogram/examples/CMakeLists.txt000066400000000000000000000005621456470715000223200ustar00rootroot00000000000000add_executable(hdr_decoder hdr_decoder.c) target_link_libraries(hdr_decoder hdr_histogram m z) install(TARGETS hdr_decoder DESTINATION bin) if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") add_executable(hiccup hiccup.c) target_link_libraries(hiccup hdr_histogram m z pthread rt) install(TARGETS hiccup DESTINATION bin) endif(${CMAKE_SYSTEM_NAME} MATCHES "Linux") diskscan-0.21/hdrhistogram/examples/hdr_decoder.c000066400000000000000000000027041456470715000221660ustar00rootroot00000000000000/** * hdr_decoder.c * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #include #include #include #include #include #include #include int main(int argc, char** argv) { int rc = 0; FILE* f; if (argc == 1) { f = stdin; } else { f = fopen(argv[1], "r"); } if (!f) { fprintf(stderr, "Failed to open file(%s):%s\n", argv[1], strerror(errno)); return -1; } struct hdr_log_reader reader; if (hdr_log_reader_init(&reader)) { fprintf(stderr, "Failed to init reader\n"); return -1; } struct hdr_histogram* h = NULL; struct timespec timestamp; struct timespec interval; rc = hdr_log_read_header(&reader, f); if(rc) { fprintf(stderr, "Failed to read header: %s\n", hdr_strerror(rc)); return -1; } while (true) { rc = hdr_log_read(&reader, f, &h, ×tamp, &interval); if (0 == rc) { hdr_percentiles_print(h, stdout, 5, 1.0, CLASSIC); } else if (EOF == rc) { break; } else { fprintf(stderr, "Failed to print histogram: %s\n", hdr_strerror(rc)); return -1; } } return 0; }diskscan-0.21/hdrhistogram/examples/hiccup.c000066400000000000000000000116141456470715000211770ustar00rootroot00000000000000/** * hiccup.c * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include static int64_t diff(struct timespec t0, struct timespec t1) { int64_t delta_us = 0; delta_us = (t1.tv_sec - t0.tv_sec) * 1000000; delta_us += (t1.tv_nsec - t0.tv_nsec) / 1000; return delta_us; } static void update_histogram(void* data, void* arg) { struct hdr_histogram* h = data; int64_t* values = arg; hdr_record_value(h, values[0]); } static void* record_hiccups(void* thread_context) { struct pollfd fd; struct timespec t0; struct timespec t1; struct itimerspec timeout; struct hdr_interval_recorder* r = thread_context; memset(&fd, 0, sizeof(struct pollfd)); memset(&timeout, 0, sizeof(struct itimerspec)); memset(&t0, 0, sizeof(struct timespec)); memset(&t1, 0, sizeof(struct timespec)); fd.fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); fd.events = POLLIN|POLLPRI|POLLRDHUP; fd.revents = 0; #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-noreturn" while (true) { timeout.it_value.tv_sec = 0; timeout.it_value.tv_nsec = 1000000; timerfd_settime(fd.fd, 0, &timeout, NULL); hdr_gettime(&t0); poll(&fd, 1, -1); hdr_gettime(&t1); int64_t delta_us = diff(t0, t1) - 1000; delta_us = delta_us < 0 ? 0 : delta_us; hdr_interval_recorder_update(r, update_histogram, &delta_us); } #pragma clang diagnostic pop pthread_exit(NULL); } struct config_t { int interval; const char* filename; }; const char* USAGE = "hiccup [-i ] [-f ]\n" " interval: Time in seconds between samples (default 1).\n" " filename: Name of the file to log to (default stdout).\n"; static int handle_opts(int argc, char** argv, struct config_t* config) { int c; int interval = 1; while ((c = getopt(argc, argv, "i:f:")) != -1) { switch (c) { case 'h': return 0; case 'i': interval = atoi(optarg); if (interval < 1) { return 0; } break; case 'f': config->filename = optarg; break; default: return 0; } } config->interval = interval < 1 ? 1 : interval; return 1; } int main(int argc, char** argv) { struct timespec timestamp; struct timespec start_timestamp; struct timespec end_timestamp; struct hdr_interval_recorder recorder; struct hdr_log_writer log_writer; struct config_t config; pthread_t recording_thread; FILE* output = stdout; memset(&config, 0, sizeof(struct config_t)); if (!handle_opts(argc, argv, &config)) { printf("%s", USAGE); return 0; } if (config.filename) { output = fopen(config.filename, "a+"); if (!output) { fprintf( stderr, "Failed to open/create file: %s, %s", config.filename, strerror(errno)); return -1; } } if (0 != hdr_interval_recorder_init(&recorder)) { fprintf(stderr, "%s\n", "Failed to init phaser"); return -1; } if (0 != hdr_init( 1, INT64_C(24) * 60 * 60 * 1000000, 3, (struct hdr_histogram**) &recorder.active)) { fprintf(stderr, "%s\n", "Failed to init hdr_histogram"); return -1; } if (0 != hdr_init( 1, INT64_C(24) * 60 * 60 * 1000000, 3, (struct hdr_histogram**) &recorder.inactive)) { fprintf(stderr, "%s\n", "Failed to init hdr_histogram"); return -1; } if (pthread_create(&recording_thread, NULL, record_hiccups, &recorder)) { fprintf(stderr, "%s\n", "Failed to create thread"); return -1; } hdr_gettime(&start_timestamp); hdr_log_writer_init(&log_writer); hdr_log_write_header(&log_writer, output, "foobar", ×tamp); #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wmissing-noreturn" while (true) { sleep(config.interval); hdr_reset(recorder.inactive); struct hdr_histogram* h = hdr_interval_recorder_sample(&recorder); hdr_gettime(&end_timestamp); timestamp = start_timestamp; hdr_gettime(&start_timestamp); hdr_log_write(&log_writer, output, ×tamp, &end_timestamp, h); fflush(output); } #pragma clang diagnostic pop pthread_exit(NULL); } diskscan-0.21/hdrhistogram/ide/000077500000000000000000000000001456470715000165005ustar00rootroot00000000000000diskscan-0.21/hdrhistogram/ide/codestyle.jar000066400000000000000000000042671456470715000212020ustar00rootroot00000000000000PK S)G codestyles/PKS)Gcodestyles/c_style.xmlVQo0~߯@7=J8Uc&q܆S-;,$D;ߝQRJZ[\[[lRm},'Xje7}6` ޗ0X0c" qzi mkly>p s$`'4p.F X@X#AKQL2?yдCc34!7Y1300cc W4 8 QLp-ΤaǂO 0O!_戒)-9I˥UE)dYRjJe)C-E^CX}|hxS~(+z=4 Cld6x4_thi5u5nyK|6Y*f&Yb|mVr+6unqiy7ug|4/NwcIiUy]&tQJ˥.oqn}Ndwuvͧ}[̂rqL، Ac?FFpmLTVSZ4?_pۨg0=ne8|oCnJv_Yvt,'8 0'eQPp_{B/(v/S̙'('(x<'Owƽ PKVB$W PKGcodestyles/Default _1_.xmlVQo0~߯@ #include #include #include "hdr_encoding.h" #include "hdr_tests.h" int zig_zag_encode_i64(uint8_t* buffer, int64_t signed_value) { int64_t value = signed_value; value = (value << 1) ^ (value >> 63); int bytesWritten = 0; if (value >> 7 == 0) { buffer[0] = (uint8_t) value; bytesWritten = 1; } else { buffer[0] = (uint8_t) ((value & 0x7F) | 0x80); if (value >> 14 == 0) { buffer[1] = (uint8_t) (value >> 7); bytesWritten = 2; } else { buffer[1] = (uint8_t) ((value >> 7 | 0x80)); if (value >> 21 == 0) { buffer[2] = (uint8_t) (value >> 14); bytesWritten = 3; } else { buffer[2] = (uint8_t) (value >> 14 | 0x80); if (value >> 28 == 0) { buffer[3] = (uint8_t) (value >> 21); bytesWritten = 4; } else { buffer[3] = (uint8_t) (value >> 21 | 0x80); if (value >> 35 == 0) { buffer[4] = (uint8_t) (value >> 28); bytesWritten = 5; } else { buffer[4] = (uint8_t) (value >> 28 | 0x80); if (value >> 42 == 0) { buffer[5] = (uint8_t) (value >> 35); bytesWritten = 6; } else { buffer[5] = (uint8_t) (value >> 35 | 0x80); if (value >> 49 == 0) { buffer[6] = (uint8_t) (value >> 42); bytesWritten = 7; } else { buffer[6] = (uint8_t) (value >> 42 | 0x80); if (value >> 56 == 0) { buffer[7] = (uint8_t) (value >> 49); bytesWritten = 8; } else { buffer[7] = (uint8_t) (value >> 49 | 0x80); buffer[8] = (uint8_t) (value >> 56); bytesWritten = 9; } } } } } } } } return bytesWritten; } int zig_zag_decode_i64(const uint8_t* buffer, int64_t* retVal) { uint64_t v = buffer[0]; uint64_t value = v & 0x7F; int bytesRead = 1; if ((v & 0x80) != 0) { bytesRead = 2; v = buffer[1]; value |= (v & 0x7F) << 7; if ((v & 0x80) != 0) { bytesRead = 3; v = buffer[2]; value |= (v & 0x7F) << 14; if ((v & 0x80) != 0) { bytesRead = 4; v = buffer[3]; value |= (v & 0x7F) << 21; if ((v & 0x80) != 0) { bytesRead = 5; v = buffer[4]; value |= (v & 0x7F) << 28; if ((v & 0x80) != 0) { bytesRead = 6; v = buffer[5]; value |= (v & 0x7F) << 35; if ((v & 0x80) != 0) { bytesRead = 7; v = buffer[6]; value |= (v & 0x7F) << 42; if ((v & 0x80) != 0) { bytesRead = 8; v = buffer[7]; value |= (v & 0x7F) << 49; if ((v & 0x80) != 0) { bytesRead = 9; v = buffer[8]; value |= v << 56; } } } } } } } } value = (value >> 1) ^ (-(value & 1)); *retVal = (int64_t) value; return bytesRead; } static const char base64_table[] = { 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/', '\0' }; static char get_base_64(uint32_t _24_bit_value, int shift) { uint32_t _6_bit_value = 0x3F & (_24_bit_value >> shift); return base64_table[_6_bit_value]; } static int from_base_64(int c) { if ('A' <= c && c <= 'Z') { return c - 'A'; } else if ('a' <= c && c <= 'z') { return (c - 'a') + 26; } else if ('0' <= c && c <= '9') { return (c - '0') + 52; } else if ('+' == c) { return 62; } else if ('/' == c) { return 63; } else if ('=' == c) { return 0; } return EINVAL; } size_t hdr_base64_encoded_len(size_t decoded_size) { return (size_t) (ceil(decoded_size / 3.0) * 4.0); } size_t hdr_base64_decoded_len(size_t encoded_size) { return (encoded_size / 4) * 3; } static void hdr_base64_encode_block_pad(const uint8_t* input, char* output, size_t pad) { uint32_t _24_bit_value = 0; switch (pad) { case 2: _24_bit_value = (input[0] << 16) + (input[1] << 8); output[0] = get_base_64(_24_bit_value, 18); output[1] = get_base_64(_24_bit_value, 12); output[2] = get_base_64(_24_bit_value, 6); output[3] = '='; break; case 1: _24_bit_value = (input[0] << 16); output[0] = get_base_64(_24_bit_value, 18); output[1] = get_base_64(_24_bit_value, 12); output[2] = '='; output[3] = '='; break; default: // No-op break; } } /** * Assumes that there is 3 input bytes and 4 output chars. */ void hdr_base64_encode_block(const uint8_t* input, char* output) { uint32_t _24_bit_value = (input[0] << 16) + (input[1] << 8) + (input[2]); output[0] = get_base_64(_24_bit_value, 18); output[1] = get_base_64(_24_bit_value, 12); output[2] = get_base_64(_24_bit_value, 6); output[3] = get_base_64(_24_bit_value, 0); } int hdr_base64_encode( const uint8_t* input, size_t input_len, char* output, size_t output_len) { if (hdr_base64_encoded_len(input_len) != output_len) { return EINVAL; } size_t i = 0; size_t j = 0; for (; input_len - i >= 3 && j < output_len; i += 3, j += 4) { hdr_base64_encode_block(&input[i], &output[j]); } size_t remaining = input_len - i; hdr_base64_encode_block_pad(&input[i], &output[j], remaining); return 0; } /** * Assumes that there is 4 input chars available and 3 output chars. */ void hdr_base64_decode_block(const char* input, uint8_t* output) { uint32_t _24_bit_value = 0; _24_bit_value |= from_base_64(input[0]) << 18; _24_bit_value |= from_base_64(input[1]) << 12; _24_bit_value |= from_base_64(input[2]) << 6; _24_bit_value |= from_base_64(input[3]); output[0] = (uint8_t) ((_24_bit_value >> 16) & 0xFF); output[1] = (uint8_t) ((_24_bit_value >> 8) & 0xFF); output[2] = (uint8_t) ((_24_bit_value) & 0xFF); } int hdr_base64_decode( const char* input, size_t input_len, uint8_t* output, size_t output_len) { size_t i, j; if (input_len < 4 || (input_len & 3) != 0 || (input_len / 4) * 3 != output_len) { return EINVAL; } for (i = 0, j = 0; i < input_len; i += 4, j += 3) { hdr_base64_decode_block(&input[i], &output[j]); } return 0; } diskscan-0.21/hdrhistogram/src/hdr_encoding.h000066400000000000000000000036141456470715000213260ustar00rootroot00000000000000// // Created by barkerm on 9/09/15. // #ifndef HDR_ENCODING_H #define HDR_ENCODING_H #include #define MAX_BYTES_LEB128 9 /** * Writes a int64_t value to the given buffer in LEB128 ZigZag encoded format * * @param buffer the buffer to write to * @param signed_value the value to write to the buffer * @return the number of bytes written to the buffer */ int zig_zag_encode_i64(uint8_t* buffer, int64_t signed_value); /** * Read an LEB128 ZigZag encoded long value from the given buffer * * @param buffer the buffer to read from * @param retVal out value to capture the read value * @return the number of bytes read from the buffer */ int zig_zag_decode_i64(const uint8_t* buffer, int64_t* signed_value); /** * Gets the length in bytes of base64 data, given the input size. * * @param decoded_size the size of the unencoded values. * @return the encoded size */ size_t hdr_base64_encoded_len(size_t decoded_size); /** * Encode into base64. * * @param input the data to encode * @param input_len the length of the data to encode * @param output the buffer to write the output to * @param output_len the number of bytes to write to the output */ int hdr_base64_encode( const uint8_t* input, size_t input_len, char* output, size_t output_len); /** * Gets the length in bytes of decoded base64 data, given the size of the base64 encoded * data. * * @param encoded_size the size of the encoded value. * @return the decoded size */ size_t hdr_base64_decoded_len(size_t encoded_size); /** * Decode from base64. * * @param input the base64 encoded data * @param input_len the size in bytes of the endcoded data * @param output the buffer to write the decoded data to * @param output_len the number of bytes to write to the output data */ int hdr_base64_decode( const char* input, size_t input_len, uint8_t* output, size_t output_len); #endif //HDR_HISTOGRAM_HDR_ENCODING_H diskscan-0.21/hdrhistogram/src/hdr_histogram.c000066400000000000000000000736671456470715000215470ustar00rootroot00000000000000/** * hdr_histogram.c * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #include #include #include #include #include #include #include #include #include "hdr_histogram.h" #include "hdr_tests.h" // ###### ####### ## ## ## ## ######## ###### // ## ## ## ## ## ## ### ## ## ## ## // ## ## ## ## ## #### ## ## ## // ## ## ## ## ## ## ## ## ## ###### // ## ## ## ## ## ## #### ## ## // ## ## ## ## ## ## ## ### ## ## ## // ###### ####### ####### ## ## ## ###### static int32_t normalize_index(const struct hdr_histogram* h, int32_t index) { if (h->normalizing_index_offset == 0) { return index; } int32_t normalized_index = index - h->normalizing_index_offset; int32_t adjustment = 0; if (normalized_index < 0) { adjustment = h->counts_len; } else if (normalized_index >= h->counts_len) { adjustment = -h->counts_len; } return normalized_index + adjustment; } static int64_t counts_get_direct(const struct hdr_histogram* h, int32_t index) { return h->counts[index]; } static int64_t counts_get_normalised(const struct hdr_histogram* h, int32_t index) { return counts_get_direct(h, normalize_index(h, index)); } static void counts_inc_normalised( struct hdr_histogram* h, int32_t index, int64_t value) { int32_t normalised_index = normalize_index(h, index); h->counts[normalised_index] += value; h->total_count += value; } static void update_min_max(struct hdr_histogram* h, int64_t value) { h->min_value = (value < h->min_value && value != 0) ? value : h->min_value; h->max_value = (value > h->max_value) ? value : h->max_value; } // ## ## ######## #### ## #### ######## ## ## // ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## #### // ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## // ####### ## #### ######## #### ## ## static int64_t power(int64_t base, int64_t exp) { int result = 1; while(exp) { result *= base; exp--; } return result; } static int32_t get_bucket_index(const struct hdr_histogram* h, int64_t value) { int32_t pow2ceiling = 64 - __builtin_clzll(value | h->sub_bucket_mask); // smallest power of 2 containing value return pow2ceiling - h->unit_magnitude - (h->sub_bucket_half_count_magnitude + 1); } static int32_t get_sub_bucket_index(int64_t value, int32_t bucket_index, int32_t unit_magnitude) { return (int32_t)(value >> (bucket_index + unit_magnitude)); } static int32_t counts_index(const struct hdr_histogram* h, int32_t bucket_index, int32_t sub_bucket_index) { // Calculate the index for the first entry in the bucket: // (The following is the equivalent of ((bucket_index + 1) * subBucketHalfCount) ): int32_t bucket_base_index = (bucket_index + 1) << h->sub_bucket_half_count_magnitude; // Calculate the offset in the bucket: int32_t offset_in_bucket = sub_bucket_index - h->sub_bucket_half_count; // The following is the equivalent of ((sub_bucket_index - subBucketHalfCount) + bucketBaseIndex; return bucket_base_index + offset_in_bucket; } static int64_t value_from_index(int32_t bucket_index, int32_t sub_bucket_index, int32_t unit_magnitude) { return ((int64_t) sub_bucket_index) << (bucket_index + unit_magnitude); } int32_t counts_index_for(const struct hdr_histogram* h, int64_t value) { int32_t bucket_index = get_bucket_index(h, value); int32_t sub_bucket_index = get_sub_bucket_index(value, bucket_index, h->unit_magnitude); return counts_index(h, bucket_index, sub_bucket_index); } int64_t hdr_value_at_index(const struct hdr_histogram *h, int32_t index) { int32_t bucket_index = (index >> h->sub_bucket_half_count_magnitude) - 1; int32_t sub_bucket_index = (index & (h->sub_bucket_half_count - 1)) + h->sub_bucket_half_count; if (bucket_index < 0) { sub_bucket_index -= h->sub_bucket_half_count; bucket_index = 0; } return value_from_index(bucket_index, sub_bucket_index, h->unit_magnitude); } int64_t hdr_size_of_equivalent_value_range(const struct hdr_histogram* h, int64_t value) { int32_t bucket_index = get_bucket_index(h, value); int32_t sub_bucket_index = get_sub_bucket_index(value, bucket_index, h->unit_magnitude); int32_t adjusted_bucket = (sub_bucket_index >= h->sub_bucket_count) ? (bucket_index + 1) : bucket_index; return INT64_C(1) << (h->unit_magnitude + adjusted_bucket); } static int64_t lowest_equivalent_value(const struct hdr_histogram* h, int64_t value) { int32_t bucket_index = get_bucket_index(h, value); int32_t sub_bucket_index = get_sub_bucket_index(value, bucket_index, h->unit_magnitude); return value_from_index(bucket_index, sub_bucket_index, h->unit_magnitude); } int64_t hdr_next_non_equivalent_value(const struct hdr_histogram *h, int64_t value) { return lowest_equivalent_value(h, value) + hdr_size_of_equivalent_value_range(h, value); } static int64_t highest_equivalent_value(const struct hdr_histogram* h, int64_t value) { return hdr_next_non_equivalent_value(h, value) - 1; } int64_t hdr_median_equivalent_value(const struct hdr_histogram *h, int64_t value) { return lowest_equivalent_value(h, value) + (hdr_size_of_equivalent_value_range(h, value) >> 1); } static int64_t non_zero_min(const struct hdr_histogram* h) { if (INT64_MAX == h->min_value) { return INT64_MAX; } return lowest_equivalent_value(h, h->min_value); } void hdr_reset_internal_counters(struct hdr_histogram* h) { int min_non_zero_index = -1; int max_index = -1; int64_t observed_total_count = 0; int i; for (i = 0; i < h->counts_len; i++) { int64_t count_at_index; if ((count_at_index = counts_get_direct(h, i)) > 0) { observed_total_count += count_at_index; max_index = i; if (min_non_zero_index == -1 && i != 0) { min_non_zero_index = i; } } } if (max_index == -1) { h->max_value = 0; } else { int64_t max_value = hdr_value_at_index(h, max_index); h->max_value = highest_equivalent_value(h, max_value); } if (min_non_zero_index == -1) { h->min_value = INT64_MAX; } else { h->min_value = hdr_value_at_index(h, min_non_zero_index); } h->total_count = observed_total_count; } static int32_t buckets_needed_to_cover_value(int64_t value, int32_t sub_bucket_count, int32_t unit_magnitude) { int64_t smallest_untrackable_value = ((int64_t) sub_bucket_count) << unit_magnitude; int32_t buckets_needed = 1; while (smallest_untrackable_value <= value) { if (smallest_untrackable_value > INT64_MAX / 2) { return buckets_needed + 1; } smallest_untrackable_value <<= 1; buckets_needed++; } return buckets_needed; } // ## ## ######## ## ## ####### ######## ## ## // ### ### ## ### ### ## ## ## ## ## ## // #### #### ## #### #### ## ## ## ## #### // ## ### ## ###### ## ### ## ## ## ######## ## // ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## // ## ## ######## ## ## ####### ## ## ## int hdr_calculate_bucket_config( int64_t lowest_trackable_value, int64_t highest_trackable_value, int significant_figures, struct hdr_histogram_bucket_config* cfg) { if (lowest_trackable_value < 1 || significant_figures < 1 || 5 < significant_figures) { return EINVAL; } else if (lowest_trackable_value * 2 > highest_trackable_value) { return EINVAL; } cfg->lowest_trackable_value = lowest_trackable_value; cfg->significant_figures = significant_figures; cfg->highest_trackable_value = highest_trackable_value; int64_t largest_value_with_single_unit_resolution = 2 * power(10, significant_figures); int32_t sub_bucket_count_magnitude = (int32_t) ceil(log(largest_value_with_single_unit_resolution) / log(2)); cfg->sub_bucket_half_count_magnitude = ((sub_bucket_count_magnitude > 1) ? sub_bucket_count_magnitude : 1) - 1; cfg->unit_magnitude = (int32_t) floor(log(lowest_trackable_value) / log(2)); cfg->sub_bucket_count = (int32_t) pow(2, (cfg->sub_bucket_half_count_magnitude + 1)); cfg->sub_bucket_half_count = cfg->sub_bucket_count / 2; cfg->sub_bucket_mask = ((int64_t) cfg->sub_bucket_count - 1) << cfg->unit_magnitude; // determine exponent range needed to support the trackable value with no overflow: cfg->bucket_count = buckets_needed_to_cover_value(highest_trackable_value, cfg->sub_bucket_count, cfg->unit_magnitude); cfg->counts_len = (cfg->bucket_count + 1) * (cfg->sub_bucket_count / 2); return 0; } void hdr_init_preallocated(struct hdr_histogram* h, struct hdr_histogram_bucket_config* cfg) { h->lowest_trackable_value = cfg->lowest_trackable_value; h->highest_trackable_value = cfg->highest_trackable_value; h->unit_magnitude = cfg->unit_magnitude; h->significant_figures = cfg->significant_figures; h->sub_bucket_half_count_magnitude = cfg->sub_bucket_half_count_magnitude; h->sub_bucket_half_count = cfg->sub_bucket_half_count; h->sub_bucket_mask = cfg->sub_bucket_mask; h->sub_bucket_count = cfg->sub_bucket_count; h->min_value = INT64_MAX; h->max_value = 0; h->normalizing_index_offset = 0; h->conversion_ratio = 1.0; h->bucket_count = cfg->bucket_count; h->counts_len = cfg->counts_len; h->total_count = 0; } int hdr_init( int64_t lowest_trackable_value, int64_t highest_trackable_value, int significant_figures, struct hdr_histogram** result) { struct hdr_histogram_bucket_config cfg; int r = hdr_calculate_bucket_config(lowest_trackable_value, highest_trackable_value, significant_figures, &cfg); if (r) { return r; } size_t histogram_size = sizeof(struct hdr_histogram) + cfg.counts_len * sizeof(int64_t); struct hdr_histogram* histogram = malloc(histogram_size); if (!histogram) { return ENOMEM; } // memset will ensure that all of the function pointers are null. memset((void*) histogram, 0, histogram_size); hdr_init_preallocated(histogram, &cfg); *result = histogram; return 0; } int hdr_alloc(int64_t highest_trackable_value, int significant_figures, struct hdr_histogram** result) { return hdr_init(1, highest_trackable_value, significant_figures, result); } // reset a histogram to zero. void hdr_reset(struct hdr_histogram *h) { h->total_count=0; h->min_value = INT64_MAX; h->max_value = 0; memset((void *) &h->counts, 0, (sizeof(int64_t) * h->counts_len)); return; } size_t hdr_get_memory_size(struct hdr_histogram *h) { return sizeof(struct hdr_histogram) + h->counts_len * sizeof(int64_t); } // ## ## ######## ######## ### ######## ######## ###### // ## ## ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## ## // ## ## ######## ## ## ## ## ## ###### ###### // ## ## ## ## ## ######### ## ## ## // ## ## ## ## ## ## ## ## ## ## ## // ####### ## ######## ## ## ## ######## ###### bool hdr_record_value(struct hdr_histogram* h, int64_t value) { return hdr_record_values(h, value, 1); } bool hdr_record_values(struct hdr_histogram* h, int64_t value, int64_t count) { if (value < 0) { return false; } int32_t counts_index = counts_index_for(h, value); if (counts_index < 0 || h->counts_len <= counts_index) { return false; } counts_inc_normalised(h, counts_index, count); update_min_max(h, value); return true; } bool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t expected_interval) { return hdr_record_corrected_values(h, value, 1, expected_interval); } bool hdr_record_corrected_values(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval) { if (!hdr_record_values(h, value, count)) { return false; } if (expected_interval <= 0 || value <= expected_interval) { return true; } int64_t missing_value = value - expected_interval; for (; missing_value >= expected_interval; missing_value -= expected_interval) { if (!hdr_record_values(h, missing_value, count)) { return false; } } return true; } int64_t hdr_add(struct hdr_histogram* h, const struct hdr_histogram* from) { struct hdr_iter iter; hdr_iter_recorded_init(&iter, from); int64_t dropped = 0; while (hdr_iter_next(&iter)) { int64_t value = iter.value; int64_t count = iter.count; if (!hdr_record_values(h, value, count)) { dropped += count; } } return dropped; } int64_t hdr_add_while_correcting_for_coordinated_omission( struct hdr_histogram* h, struct hdr_histogram* from, int64_t expected_interval) { struct hdr_iter iter; hdr_iter_recorded_init(&iter, from); int64_t dropped = 0; while (hdr_iter_next(&iter)) { int64_t value = iter.value; int64_t count = iter.count; if (!hdr_record_corrected_values(h, value, count, expected_interval)) { dropped += count; } } return dropped; } // ## ## ### ## ## ## ######## ###### // ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ###### ###### // ## ## ######### ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## // ### ## ## ######## ####### ######## ###### int64_t hdr_max(const struct hdr_histogram* h) { if (0 == h->max_value) { return 0; } return highest_equivalent_value(h, h->max_value); } int64_t hdr_min(const struct hdr_histogram* h) { if (0 < hdr_count_at_index(h, 0)) { return 0; } return non_zero_min(h); } int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile) { struct hdr_iter iter; hdr_iter_init(&iter, h); double requested_percentile = percentile < 100.0 ? percentile : 100.0; int64_t count_at_percentile = (int64_t) (((requested_percentile / 100) * h->total_count) + 0.5); count_at_percentile = count_at_percentile > 1 ? count_at_percentile : 1; int64_t total = 0; while (hdr_iter_next(&iter)) { total += iter.count; if (total >= count_at_percentile) { int64_t value_from_index = iter.value; return highest_equivalent_value(h, value_from_index); } } return 0; } double hdr_mean(const struct hdr_histogram* h) { struct hdr_iter iter; int64_t total = 0; hdr_iter_init(&iter, h); while (hdr_iter_next(&iter)) { if (0 != iter.count) { total += iter.count * hdr_median_equivalent_value(h, iter.value); } } return (total * 1.0) / h->total_count; } double hdr_stddev(const struct hdr_histogram* h) { double mean = hdr_mean(h); double geometric_dev_total = 0.0; struct hdr_iter iter; hdr_iter_init(&iter, h); while (hdr_iter_next(&iter)) { if (0 != iter.count) { double dev = (hdr_median_equivalent_value(h, iter.value) * 1.0) - mean; geometric_dev_total += (dev * dev) * iter.count; } } return sqrt(geometric_dev_total / h->total_count); } bool hdr_values_are_equivalent(const struct hdr_histogram* h, int64_t a, int64_t b) { return lowest_equivalent_value(h, a) == lowest_equivalent_value(h, b); } int64_t hdr_lowest_equivalent_value(const struct hdr_histogram* h, int64_t value) { return lowest_equivalent_value(h, value); } int64_t hdr_count_at_value(const struct hdr_histogram* h, int64_t value) { return counts_get_normalised(h, counts_index_for(h, value)); } int64_t hdr_count_at_index(const struct hdr_histogram* h, int32_t index) { return counts_get_normalised(h, index); } // #### ######## ######## ######## ### ######## ####### ######## ###### // ## ## ## ## ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## ## ## ## // ## ## ###### ######## ## ## ## ## ## ######## ###### // ## ## ## ## ## ######### ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## ## ## ## ## // #### ## ######## ## ## ## ## ## ####### ## ## ###### static bool has_buckets(struct hdr_iter* iter) { return iter->counts_index < iter->h->counts_len; } static bool has_next(struct hdr_iter* iter) { return iter->cumulative_count < iter->h->total_count; } static bool move_next(struct hdr_iter* iter) { iter->counts_index++; if (!has_buckets(iter)) { return false; } iter->count = counts_get_normalised(iter->h, iter->counts_index); iter->cumulative_count += iter->count; iter->value = hdr_value_at_index(iter->h, iter->counts_index); iter->highest_equivalent_value = highest_equivalent_value(iter->h, iter->value); iter->lowest_equivalent_value = lowest_equivalent_value(iter->h, iter->value); iter->median_equivalent_value = hdr_median_equivalent_value(iter->h, iter->value); return true; } static int64_t peek_next_value_from_index(struct hdr_iter* iter) { return hdr_value_at_index(iter->h, iter->counts_index + 1); } static bool next_value_greater_than_reporting_level_upper_bound( struct hdr_iter *iter, int64_t reporting_level_upper_bound) { if (iter->counts_index >= iter->h->counts_len) { return false; } return peek_next_value_from_index(iter) > reporting_level_upper_bound; } static bool _basic_iter_next(struct hdr_iter *iter) { if (!has_next(iter)) { return false; } move_next(iter); return true; } static void _update_iterated_values(struct hdr_iter* iter, int64_t new_value_iterated_to) { iter->value_iterated_from = iter->value_iterated_to; iter->value_iterated_to = new_value_iterated_to; } static bool _all_values_iter_next(struct hdr_iter* iter) { bool result = move_next(iter); if (result) { _update_iterated_values(iter, iter->value); } return result; } void hdr_iter_init(struct hdr_iter* iter, const struct hdr_histogram* h) { iter->h = h; iter->counts_index = -1; iter->count = 0; iter->cumulative_count = 0; iter->value = 0; iter->highest_equivalent_value = 0; iter->value_iterated_from = 0; iter->value_iterated_to = 0; iter->_next_fp = _all_values_iter_next; } bool hdr_iter_next(struct hdr_iter* iter) { return iter->_next_fp(iter); } // ######## ######## ######## ###### ######## ## ## ######## #### ## ######## ###### // ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## ## // ## ## ## ## ## ## ## #### ## ## ## ## ## ## // ######## ###### ######## ## ###### ## ## ## ## ## ## ###### ###### // ## ## ## ## ## ## ## #### ## ## ## ## ## // ## ## ## ## ## ## ## ## ### ## ## ## ## ## ## // ## ######## ## ## ###### ######## ## ## ## #### ######## ######## ###### static bool _percentile_iter_next(struct hdr_iter* iter) { struct hdr_iter_percentiles* percentiles = &iter->specifics.percentiles; if (!has_next(iter)) { if (percentiles->seen_last_value) { return false; } percentiles->seen_last_value = true; percentiles->percentile = 100.0; return true; } if (iter->counts_index == -1 && !_basic_iter_next(iter)) { return false; } do { double current_percentile = (100.0 * (double) iter->cumulative_count) / iter->h->total_count; if (iter->count != 0 && percentiles->percentile_to_iterate_to <= current_percentile) { _update_iterated_values(iter, highest_equivalent_value(iter->h, iter->value)); percentiles->percentile = percentiles->percentile_to_iterate_to; int64_t half_distance = (int64_t) pow(2, (int64_t) (log(100 / (100.0 - (percentiles->percentile_to_iterate_to))) / log(2)) + 1); int64_t percentile_reporting_ticks = percentiles->ticks_per_half_distance * half_distance; percentiles->percentile_to_iterate_to += 100.0 / percentile_reporting_ticks; return true; } } while (_basic_iter_next(iter)); return true; } void hdr_iter_percentile_init(struct hdr_iter* iter, const struct hdr_histogram* h, int32_t ticks_per_half_distance) { iter->h = h; hdr_iter_init(iter, h); iter->specifics.percentiles.seen_last_value = false; iter->specifics.percentiles.ticks_per_half_distance = ticks_per_half_distance; iter->specifics.percentiles.percentile_to_iterate_to = 0.0; iter->specifics.percentiles.percentile = 0.0; iter->_next_fp = _percentile_iter_next; } static void format_line_string(char* str, size_t len, int significant_figures, format_type format) { const char* format_str = "%s%d%s"; switch (format) { case CSV: snprintf(str, len, format_str, "%.", significant_figures, "f,%f,%d,%.2f\n"); break; case CLASSIC: snprintf(str, len, format_str, "%12.", significant_figures, "f %12f %12d %12.2f\n"); break; default: snprintf(str, len, format_str, "%12.", significant_figures, "f %12f %12d %12.2f\n"); } } // ######## ######## ###### ####### ######## ######## ######## ######## // ## ## ## ## ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## ## ## ## // ######## ###### ## ## ## ######## ## ## ###### ## ## // ## ## ## ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## ## ## ## ## // ## ## ######## ###### ####### ## ## ######## ######## ######## static bool _recorded_iter_next(struct hdr_iter* iter) { while (_basic_iter_next(iter)) { if (iter->count != 0) { _update_iterated_values(iter, iter->value); iter->specifics.recorded.count_added_in_this_iteration_step = iter->count; return true; } } return false; } void hdr_iter_recorded_init(struct hdr_iter* iter, const struct hdr_histogram* h) { hdr_iter_init(iter, h); iter->specifics.recorded.count_added_in_this_iteration_step = 0; iter->_next_fp = _recorded_iter_next; } // ## #### ## ## ######## ### ######## // ## ## ### ## ## ## ## ## ## // ## ## #### ## ## ## ## ## ## // ## ## ## ## ## ###### ## ## ######## // ## ## ## #### ## ######### ## ## // ## ## ## ### ## ## ## ## ## // ######## #### ## ## ######## ## ## ## ## static bool _iter_linear_next(struct hdr_iter* iter) { struct hdr_iter_linear* linear = &iter->specifics.linear; linear->count_added_in_this_iteration_step = 0; if (has_next(iter) || next_value_greater_than_reporting_level_upper_bound( iter, linear->next_value_reporting_level_lowest_equivalent)) { do { if (iter->value >= linear->next_value_reporting_level_lowest_equivalent) { _update_iterated_values(iter, linear->next_value_reporting_level); linear->next_value_reporting_level += linear->value_units_per_bucket; linear->next_value_reporting_level_lowest_equivalent = lowest_equivalent_value(iter->h, linear->next_value_reporting_level); return true; } if (!move_next(iter)) { break; } linear->count_added_in_this_iteration_step += iter->count; } while (true); } return false; } void hdr_iter_linear_init(struct hdr_iter* iter, const struct hdr_histogram* h, int64_t value_units_per_bucket) { hdr_iter_init(iter, h); iter->specifics.linear.count_added_in_this_iteration_step = 0; iter->specifics.linear.value_units_per_bucket = value_units_per_bucket; iter->specifics.linear.next_value_reporting_level = value_units_per_bucket; iter->specifics.linear.next_value_reporting_level_lowest_equivalent = lowest_equivalent_value(h, value_units_per_bucket); iter->_next_fp = _iter_linear_next; } // ## ####### ###### ### ######## #### ######## ## ## ## ## #### ###### // ## ## ## ## ## ## ## ## ## ## ## ## ## ### ### ## ## ## // ## ## ## ## ## ## ## ## ## ## ## ## #### #### ## ## // ## ## ## ## #### ## ## ######## ## ## ######### ## ### ## ## ## // ## ## ## ## ## ######### ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## // ######## ####### ###### ## ## ## ## #### ## ## ## ## ## #### ###### static bool _log_iter_next(struct hdr_iter *iter) { struct hdr_iter_log* logarithmic = &iter->specifics.log; logarithmic->count_added_in_this_iteration_step = 0; if (has_next(iter) || next_value_greater_than_reporting_level_upper_bound( iter, logarithmic->next_value_reporting_level_lowest_equivalent)) { do { if (iter->value >= logarithmic->next_value_reporting_level_lowest_equivalent) { _update_iterated_values(iter, logarithmic->next_value_reporting_level); logarithmic->next_value_reporting_level *= logarithmic->log_base; logarithmic->next_value_reporting_level_lowest_equivalent = lowest_equivalent_value(iter->h, logarithmic->next_value_reporting_level); return true; } if (!move_next(iter)) { break; } logarithmic->count_added_in_this_iteration_step += iter->count; } while (true); } return false; } void hdr_iter_log_init( struct hdr_iter* iter, const struct hdr_histogram* h, int64_t value_units_first_bucket, double log_base) { hdr_iter_init(iter, h); iter->specifics.log.count_added_in_this_iteration_step = 0; iter->specifics.log.log_base = log_base; iter->specifics.log.next_value_reporting_level = value_units_first_bucket; iter->specifics.log.next_value_reporting_level_lowest_equivalent = lowest_equivalent_value(h, value_units_first_bucket); iter->_next_fp = _log_iter_next; } // Printing. static const char* format_head_string(format_type format) { switch (format) { case CSV: return "%s,%s,%s,%s\n"; case CLASSIC: return "%12s %12s %12s %12s\n\n"; default: return "%12s %12s %12s %12s\n\n"; } } static const char CLASSIC_FOOTER[] = "#[Mean = %12.3f, StdDeviation = %12.3f]\n" "#[Max = %12.3f, Total count = %12" PRIu64 "]\n" "#[Buckets = %12d, SubBuckets = %12d]\n"; int hdr_percentiles_print( struct hdr_histogram* h, FILE* stream, int32_t ticks_per_half_distance, double value_scale, format_type format) { char line_format[25]; format_line_string(line_format, 25, h->significant_figures, format); const char* head_format = format_head_string(format); int rc = 0; struct hdr_iter iter; hdr_iter_percentile_init(&iter, h, ticks_per_half_distance); if (fprintf( stream, head_format, "Value", "Percentile", "TotalCount", "1/(1-Percentile)") < 0) { rc = EIO; goto cleanup; } struct hdr_iter_percentiles * percentiles = &iter.specifics.percentiles; while (hdr_iter_next(&iter)) { double value = iter.highest_equivalent_value / value_scale; double percentile = percentiles->percentile / 100.0; int64_t total_count = iter.cumulative_count; double inverted_percentile = (1.0 / (1.0 - percentile)); if (fprintf( stream, line_format, value, percentile, total_count, inverted_percentile) < 0) { rc = EIO; goto cleanup; } } if (CLASSIC == format) { double mean = hdr_mean(h) / value_scale; double stddev = hdr_stddev(h) / value_scale; double max = hdr_max(h) / value_scale; if (fprintf( stream, CLASSIC_FOOTER, mean, stddev, max, h->total_count, h->bucket_count, h->sub_bucket_count) < 0) { rc = EIO; goto cleanup; } } cleanup: return rc; } diskscan-0.21/hdrhistogram/src/hdr_histogram.h000066400000000000000000000321451456470715000215360ustar00rootroot00000000000000/** * hdr_histogram.h * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ * * The source for the hdr_histogram utilises a few C99 constructs, specifically * the use of stdint/stdbool and inline variable declaration. */ #ifndef HDR_HISTOGRAM_H #define HDR_HISTOGRAM_H 1 #include #include #include struct hdr_histogram { int64_t lowest_trackable_value; int64_t highest_trackable_value; int32_t unit_magnitude; int32_t significant_figures; int32_t sub_bucket_half_count_magnitude; int32_t sub_bucket_half_count; int64_t sub_bucket_mask; int32_t sub_bucket_count; int32_t bucket_count; int64_t min_value; int64_t max_value; int32_t normalizing_index_offset; double conversion_ratio; int32_t counts_len; int64_t total_count; int64_t counts[0]; }; /** * Allocate the memory and initialise the hdr_histogram. * * Due to the size of the histogram being the result of some reasonably * involved math on the input parameters this function it is tricky to stack allocate. * The histogram is allocated in a single contigious block so can be delete via free, * without any structure specific destructor. * * @param lowest_trackable_value The smallest possible value to be put into the * histogram. * @param highest_trackable_value The largest possible value to be put into the * histogram. * @param significant_figures The level of precision for this histogram, i.e. the number * of figures in a decimal number that will be maintained. E.g. a value of 3 will mean * the results from the histogram will be accurate up to the first three digits. Must * be a value between 1 and 5 (inclusive). * @param result Output parameter to capture allocated histogram. * @return 0 on success, EINVAL if lowest_trackable_value is < 1 or the * significant_figure value is outside of the allowed range, ENOMEM if malloc * failed. */ int hdr_init( int64_t lowest_trackable_value, int64_t highest_trackable_value, int significant_figures, struct hdr_histogram** result); /** * Allocate the memory and initialise the hdr_histogram. This is the equivalent of calling * hdr_init(1, highest_trackable_value, significant_figures, result); * * @deprecated use hdr_init. */ int hdr_alloc(int64_t highest_trackable_value, int significant_figures, struct hdr_histogram** result); /** * Reset a histogram to zero - empty out a histogram and re-initialise it * * If you want to re-use an existing histogram, but reset everything back to zero, this * is the routine to use. * * @param h The histogram you want to reset to empty. * */ void hdr_reset(struct hdr_histogram *h); /** * Get the memory size of the hdr_histogram. * * @param h "This" pointer * @return The amount of memory used by the hdr_histogram in bytes */ size_t hdr_get_memory_size(struct hdr_histogram *h); /** * Records a value in the histogram, will round this value of to a precision at or better * than the significant_figure specified at construction time. * * @param h "This" pointer * @param value Value to add to the histogram * @return false if the value is larger than the highest_trackable_value and can't be recorded, * true otherwise. */ bool hdr_record_value(struct hdr_histogram* h, int64_t value); /** * Records count values in the histogram, will round this value of to a * precision at or better than the significant_figure specified at construction * time. * * @param h "This" pointer * @param value Value to add to the histogram * @param count Number of 'value's to add to the histogram * @return false if any value is larger than the highest_trackable_value and can't be recorded, * true otherwise. */ bool hdr_record_values(struct hdr_histogram* h, int64_t value, int64_t count); /** * Record a value in the histogram and backfill based on an expected interval. * * Records a value in the histogram, will round this value of to a precision at or better * than the significant_figure specified at contruction time. This is specifically used * for recording latency. If the value is larger than the expected_interval then the * latency recording system has experienced co-ordinated omission. This method fills in the * values that would have occured had the client providing the load not been blocked. * @param h "This" pointer * @param value Value to add to the histogram * @param expected_interval The delay between recording values. * @return false if the value is larger than the highest_trackable_value and can't be recorded, * true otherwise. */ bool hdr_record_corrected_value(struct hdr_histogram* h, int64_t value, int64_t expexcted_interval); /** * Record a value in the histogram 'count' times. Applies the same correcting logic * as 'hdr_record_corrected_value'. * * @param h "This" pointer * @param value Value to add to the histogram * @param count Number of 'value's to add to the histogram * @param expected_interval The delay between recording values. * @return false if the value is larger than the highest_trackable_value and can't be recorded, * true otherwise. */ bool hdr_record_corrected_values(struct hdr_histogram* h, int64_t value, int64_t count, int64_t expected_interval); /** * Adds all of the values from 'from' to 'this' histogram. Will return the * number of values that are dropped when copying. Values will be dropped * if they around outside of h.lowest_trackable_value and * h.highest_trackable_value. * * @param h "This" pointer * @param from Histogram to copy values from. * @return The number of values dropped when copying. */ int64_t hdr_add(struct hdr_histogram* h, const struct hdr_histogram* from); /** * Adds all of the values from 'from' to 'this' histogram. Will return the * number of values that are dropped when copying. Values will be dropped * if they around outside of h.lowest_trackable_value and * h.highest_trackable_value. * * @param h "This" pointer * @param from Histogram to copy values from. * @return The number of values dropped when copying. */ int64_t hdr_add_while_correcting_for_coordinated_omission( struct hdr_histogram* h, struct hdr_histogram* from, int64_t expected_interval); /** * Get minimum value from the histogram. Will return 2^63-1 if the histogram * is empty. * * @param h "This" pointer */ int64_t hdr_min(const struct hdr_histogram* h); /** * Get maximum value from the histogram. Will return 0 if the histogram * is empty. * * @param h "This" pointer */ int64_t hdr_max(const struct hdr_histogram* h); /** * Get the value at a specific percentile. * * @param h "This" pointer. * @param percentile The percentile to get the value for */ int64_t hdr_value_at_percentile(const struct hdr_histogram* h, double percentile); /** * Gets the standard deviation for the values in the histogram. * * @param h "This" pointer * @return The standard deviation */ double hdr_stddev(const struct hdr_histogram* h); /** * Gets the mean for the values in the histogram. * * @param h "This" pointer * @return The mean */ double hdr_mean(const struct hdr_histogram* h); /** * Determine if two values are equivalent with the histogram's resolution. * Where "equivalent" means that value samples recorded for any two * equivalent values are counted in a common total count. * * @param h "This" pointer * @param a first value to compare * @param b second value to compare * @return 'true' if values are equivalent with the histogram's resolution. */ bool hdr_values_are_equivalent(const struct hdr_histogram* h, int64_t a, int64_t b); /** * Get the lowest value that is equivalent to the given value within the histogram's resolution. * Where "equivalent" means that value samples recorded for any two * equivalent values are counted in a common total count. * * @param h "This" pointer * @param value The given value * @return The lowest value that is equivalent to the given value within the histogram's resolution. */ int64_t hdr_lowest_equivalent_value(const struct hdr_histogram* h, int64_t value); /** * Get the count of recorded values at a specific value * (to within the histogram resolution at the value level). * * @param h "This" pointer * @param value The value for which to provide the recorded count * @return The total count of values recorded in the histogram within the value range that is * {@literal >=} lowestEquivalentValue(value) and {@literal <=} highestEquivalentValue(value) */ int64_t hdr_count_at_value(const struct hdr_histogram* h, int64_t value); int64_t hdr_count_at_index(const struct hdr_histogram* h, int32_t index); int64_t hdr_value_at_index(const struct hdr_histogram* h, int32_t index); struct hdr_iter_percentiles { bool seen_last_value; int32_t ticks_per_half_distance; double percentile_to_iterate_to; double percentile; }; struct hdr_iter_recorded { int64_t count_added_in_this_iteration_step; }; struct hdr_iter_linear { int64_t value_units_per_bucket; int64_t count_added_in_this_iteration_step; int64_t next_value_reporting_level; int64_t next_value_reporting_level_lowest_equivalent; }; struct hdr_iter_log { double log_base; int64_t count_added_in_this_iteration_step; int64_t next_value_reporting_level; int64_t next_value_reporting_level_lowest_equivalent; }; /** * The basic iterator. This is a generic structure * that supports all of the types of iteration. Use * the appropriate initialiser to get the desired * iteration. * * @ */ struct hdr_iter { const struct hdr_histogram* h; /** raw index into the counts array */ int32_t counts_index; /** value directly from array for the current counts_index */ int64_t count; /** sum of all of the counts up to and including the count at this index */ int64_t cumulative_count; /** The current value based on counts_index */ int64_t value; int64_t highest_equivalent_value; int64_t lowest_equivalent_value; int64_t median_equivalent_value; int64_t value_iterated_from; int64_t value_iterated_to; union { struct hdr_iter_percentiles percentiles; struct hdr_iter_recorded recorded; struct hdr_iter_linear linear; struct hdr_iter_log log; } specifics; bool (*_next_fp)(struct hdr_iter* iter); }; /** * Initalises the basic iterator. * * @param itr 'This' pointer * @param h The histogram to iterate over */ void hdr_iter_init(struct hdr_iter* iter, const struct hdr_histogram* h); /** * Initialise the iterator for use with percentiles. */ void hdr_iter_percentile_init(struct hdr_iter* iter, const struct hdr_histogram* h, int32_t ticks_per_half_distance); /** * Initialise the iterator for use with recorded values. */ void hdr_iter_recorded_init(struct hdr_iter* iter, const struct hdr_histogram* h); /** * Initialise the iterator for use with linear values. */ void hdr_iter_linear_init( struct hdr_iter* iter, const struct hdr_histogram* h, int64_t value_units_per_bucket); /** * Initialise the iterator for use with logarithmic values */ void hdr_iter_log_init( struct hdr_iter* iter, const struct hdr_histogram* h, int64_t value_units_first_bucket, double log_base); /** * Iterate to the next value for the iterator. If there are no more values * available return faluse. * * @param itr 'This' pointer * @return 'false' if there are no values remaining for this iterator. */ bool hdr_iter_next(struct hdr_iter* iter); typedef enum { CLASSIC, CSV } format_type; /** * Print out a percentile based histogram to the supplied stream. Note that * this call will not flush the FILE, this is left up to the user. * * @param h 'This' pointer * @param stream The FILE to write the output to * @param ticks_per_half_distance The number of iteration steps per half-distance to 100% * @param value_scale Scale the output values by this amount * @param format_type Format to use, e.g. CSV. * @return 0 on success, error code on failure. EIO if an error occurs writing * the output. */ int hdr_percentiles_print( struct hdr_histogram* h, FILE* stream, int32_t ticks_per_half_distance, double value_scale, format_type format); /** * Internal allocation methods, used by hdr_dbl_histogram. */ struct hdr_histogram_bucket_config { int64_t lowest_trackable_value; int64_t highest_trackable_value; int64_t unit_magnitude; int64_t significant_figures; int32_t sub_bucket_half_count_magnitude; int32_t sub_bucket_half_count; int64_t sub_bucket_mask; int32_t sub_bucket_count; int32_t bucket_count; int32_t counts_len; }; int hdr_calculate_bucket_config( int64_t lowest_trackable_value, int64_t highest_trackable_value, int significant_figures, struct hdr_histogram_bucket_config* cfg); void hdr_init_preallocated(struct hdr_histogram* h, struct hdr_histogram_bucket_config* cfg); int64_t hdr_size_of_equivalent_value_range(const struct hdr_histogram *h, int64_t value); int64_t hdr_next_non_equivalent_value(const struct hdr_histogram *h, int64_t value); int64_t hdr_median_equivalent_value(const struct hdr_histogram *h, int64_t value); #endif diskscan-0.21/hdrhistogram/src/hdr_histogram_log.c000066400000000000000000000731021456470715000223700ustar00rootroot00000000000000/** * hdr_histogram_log.c * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #include #include #include #include #include #include #include #include #include #include "hdr_encoding.h" #include "hdr_histogram.h" #include "hdr_histogram_log.h" #include "hdr_tests.h" #ifdef __APPLE__ #include #define htobe16(x) OSSwapHostToBigInt16(x) #define htole16(x) OSSwapHostToLittleInt16(x) #define be16toh(x) OSSwapBigToHostInt16(x) #define le16toh(x) OSSwapLittleToHostInt16(x) #define htobe32(x) OSSwapHostToBigInt32(x) #define htole32(x) OSSwapHostToLittleInt32(x) #define be32toh(x) OSSwapBigToHostInt32(x) #define le32toh(x) OSSwapLittleToHostInt32(x) #define htobe64(x) OSSwapHostToBigInt64(x) #define htole64(x) OSSwapHostToLittleInt64(x) #define be64toh(x) OSSwapBigToHostInt64(x) #define le64toh(x) OSSwapLittleToHostInt64(x) #elif defined(__FreeBSD__) #include #endif // Private prototypes useful for the logger int32_t counts_index_for(const struct hdr_histogram* h, int64_t value); #define FAIL_AND_CLEANUP(label, error_name, error) \ do \ { \ error_name = error; \ goto label; \ } \ while (0) static int realloc_buffer( void** buffer, size_t nmemb, ssize_t size) { size_t len = nmemb * size; if (NULL == *buffer) { *buffer = malloc(len); } else { *buffer = realloc(*buffer, len); } if (NULL == *buffer) { return ENOMEM; } else { memset(*buffer, 0, len); return 0; } } // ###### ######## ######## #### ## ## ###### ###### // ## ## ## ## ## ## ### ## ## ## ## ## // ## ## ## ## ## #### ## ## ## // ###### ## ######## ## ## ## ## ## #### ###### // ## ## ## ## ## ## #### ## ## ## // ## ## ## ## ## ## ## ### ## ## ## ## // ###### ## ## ## #### ## ## ###### ###### static ssize_t null_trailing_whitespace(char* s, ssize_t len) { ssize_t i = len; while (--i != -1) { if (isspace(s[i])) { s[i] = '\0'; } else { return i + 1; } } return 0; } // ######## ## ## ###### ####### ######## #### ## ## ###### // ## ### ## ## ## ## ## ## ## ## ### ## ## ## // ## #### ## ## ## ## ## ## ## #### ## ## // ###### ## ## ## ## ## ## ## ## ## ## ## ## ## #### // ## ## #### ## ## ## ## ## ## ## #### ## ## // ## ## ### ## ## ## ## ## ## ## ## ### ## ## // ######## ## ## ###### ####### ######## #### ## ## ###### static const int32_t V0_ENCODING_COOKIE = 0x1c849308; static const int32_t V0_COMPRESSION_COOKIE = 0x1c849309; static const int32_t V1_ENCODING_COOKIE = 0x1c849301; static const int32_t V1_COMPRESSION_COOKIE = 0x1c849302; static const int32_t V2_ENCODING_COOKIE = 0x1c849303; static const int32_t V2_COMPRESSION_COOKIE = 0x1c849304; static int32_t get_cookie_base(int32_t cookie) { return (cookie & ~0xf0); } static int32_t word_size_from_cookie(int32_t cookie) { return (cookie & 0xf0) >> 4; } const char* hdr_strerror(int errnum) { switch (errnum) { case HDR_COMPRESSION_COOKIE_MISMATCH: return "Compression cookie mismatch"; case HDR_ENCODING_COOKIE_MISMATCH: return "Encoding cookie mismatch"; case HDR_DEFLATE_INIT_FAIL: return "Deflate initialisation failed"; case HDR_DEFLATE_FAIL: return "Deflate failed"; case HDR_INFLATE_INIT_FAIL: return "Inflate initialisation failed"; case HDR_INFLATE_FAIL: return "Inflate failed"; case HDR_LOG_INVALID_VERSION: return "Log - invalid version in log header"; case HDR_TRAILING_ZEROS_INVALID: return "Invalid number of trailing zeros"; case HDR_VALUE_TRUNCATED: return "Truncated value found when decoding"; case HDR_ENCODED_INPUT_TOO_LONG: return "The encoded input exceeds the size of the histogram"; default: return strerror(errnum); } } static void strm_init(z_stream* strm) { strm->zfree = NULL; strm->zalloc = NULL; strm->opaque = NULL; strm->next_in = NULL; strm->avail_in = 0; } union uint64_dbl_cvt { uint64_t l; double d; }; static double int64_bits_to_double(int64_t i) { union uint64_dbl_cvt x; x.l = (uint64_t) i; return x.d; } static uint64_t double_to_int64_bits(double d) { union uint64_dbl_cvt x; x.d = d; return x.l; } typedef struct __attribute__((__packed__)) { int32_t cookie; int32_t significant_figures; int64_t lowest_trackable_value; int64_t highest_trackable_value; int64_t total_count; int64_t counts[0]; } _encoding_flyweight_v0; typedef struct __attribute__((__packed__)) { int32_t cookie; int32_t payload_len; int32_t normalizing_index_offset; int32_t significant_figures; int64_t lowest_trackable_value; int64_t highest_trackable_value; uint64_t conversion_ratio_bits; uint8_t counts[0]; } _encoding_flyweight_v1; typedef struct __attribute__((__packed__)) { int32_t cookie; int32_t length; uint8_t data[0]; } _compression_flyweight; int hdr_encode_compressed( struct hdr_histogram* h, uint8_t** compressed_histogram, size_t* compressed_len) { _encoding_flyweight_v1* encoded = NULL; _compression_flyweight* compressed = NULL; int result = 0; int32_t len_to_max = counts_index_for(h, h->max_value) + 1; int32_t counts_limit = len_to_max < h->counts_len ? len_to_max : h->counts_len; const size_t encoded_len = sizeof(_encoding_flyweight_v1) + MAX_BYTES_LEB128 * (size_t) counts_limit; if ((encoded = (_encoding_flyweight_v1*) calloc(encoded_len, sizeof(uint8_t))) == NULL) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } int data_index = 0; int i; for (i = 0; i < counts_limit;) { int64_t value = h->counts[i]; i++; if (value == 0) { int32_t zeros = 1; while (i < counts_limit && 0 == h->counts[i]) { zeros++; i++; } data_index += zig_zag_encode_i64(&encoded->counts[data_index], -zeros); } else { data_index += zig_zag_encode_i64(&encoded->counts[data_index], value); } } size_t encoded_size = sizeof(_encoding_flyweight_v1) + data_index; encoded->cookie = htobe32(V2_ENCODING_COOKIE | 0x10); encoded->payload_len = htobe32(encoded_size); encoded->normalizing_index_offset = htobe32(h->normalizing_index_offset); encoded->significant_figures = htobe32(h->significant_figures); encoded->lowest_trackable_value = htobe64(h->lowest_trackable_value); encoded->highest_trackable_value = htobe64(h->highest_trackable_value); encoded->conversion_ratio_bits = htobe64(double_to_int64_bits(h->conversion_ratio)); // Estimate the size of the compressed histogram. uLongf destLen = compressBound(encoded_size); size_t compressed_size = sizeof(_compression_flyweight) + destLen; if ((compressed = (_compression_flyweight*) malloc(compressed_size)) == NULL) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } if (Z_OK != compress(compressed->data, &destLen, (Bytef*) encoded, encoded_size)) { FAIL_AND_CLEANUP(cleanup, result, HDR_DEFLATE_FAIL); } compressed->cookie = htobe32(V2_COMPRESSION_COOKIE | 0x10); compressed->length = htobe32((int32_t)destLen); *compressed_histogram = (uint8_t*) compressed; *compressed_len = sizeof(_compression_flyweight) + destLen; cleanup: free(encoded); if (result == HDR_DEFLATE_FAIL) { free(compressed); } return result; } // ######## ######## ###### ####### ######## #### ## ## ###### // ## ## ## ## ## ## ## ## ## ## ### ## ## ## // ## ## ## ## ## ## ## ## ## #### ## ## // ## ## ###### ## ## ## ## ## ## ## ## ## ## #### // ## ## ## ## ## ## ## ## ## ## #### ## ## // ## ## ## ## ## ## ## ## ## ## ## ### ## ## // ######## ######## ###### ####### ######## #### ## ## ###### // Prototype to avoid exposing in header void hdr_reset_internal_counters(struct hdr_histogram* h); static void _apply_to_counts_16(struct hdr_histogram* h, const int16_t* counts_data, const int32_t counts_limit) { int i; for (i = 0; i < counts_limit; i++) { h->counts[i] = be16toh(counts_data[i]); } } static void _apply_to_counts_32(struct hdr_histogram* h, const int32_t* counts_data, const int32_t counts_limit) { int i; for (i = 0; i < counts_limit; i++) { h->counts[i] = be32toh(counts_data[i]); } } static void _apply_to_counts_64(struct hdr_histogram* h, const int64_t* counts_data, const int32_t counts_limit) { int i; for (i = 0; i < counts_limit; i++) { h->counts[i] = be64toh(counts_data[i]); } } static int _apply_to_counts_zz(struct hdr_histogram* h, const uint8_t* counts_data, const int32_t data_limit) { int64_t data_index = 0; int32_t counts_index = 0; int64_t value; while (data_index < data_limit && counts_index < h->counts_len) { data_index += zig_zag_decode_i64(&counts_data[data_index], &value); if (value < 0) { int64_t zeros = -value; if (value <= INT32_MIN || counts_index + zeros > h->counts_len) { return HDR_TRAILING_ZEROS_INVALID; } counts_index += (int32_t) zeros; } else { h->counts[counts_index] = value; counts_index++; } } if (data_index > data_limit) { return HDR_VALUE_TRUNCATED; } else if (data_index < data_limit) { return HDR_ENCODED_INPUT_TOO_LONG; } return 0; } static int _apply_to_counts( struct hdr_histogram* h, const int32_t word_size, const uint8_t* counts_data, const int32_t counts_limit) { switch (word_size) { case 2: _apply_to_counts_16(h, (int16_t*) counts_data, counts_limit); return 0; case 4: _apply_to_counts_32(h, (int32_t*) counts_data, counts_limit); return 0; case 8: _apply_to_counts_64(h, (int64_t*) counts_data, counts_limit); return 0; case 1: return _apply_to_counts_zz(h, counts_data, counts_limit); default: return -1; } } static int hdr_decode_compressed_v0( _compression_flyweight* compression_flyweight, size_t length, struct hdr_histogram** histogram) { struct hdr_histogram* h = NULL; int result = 0; uint8_t* counts_array = NULL; _encoding_flyweight_v0 encoding_flyweight; z_stream strm; strm_init(&strm); if (inflateInit(&strm) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t compressed_length = be32toh(compression_flyweight->length); if (compressed_length < 0 || length - sizeof(_compression_flyweight) < (size_t)compressed_length) { FAIL_AND_CLEANUP(cleanup, result, EINVAL); } strm.next_in = compression_flyweight->data; strm.avail_in = (uInt) compressed_length; strm.next_out = (uint8_t *) &encoding_flyweight; strm.avail_out = sizeof(_encoding_flyweight_v0); if (inflate(&strm, Z_SYNC_FLUSH) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t encoding_cookie = get_cookie_base(be32toh(encoding_flyweight.cookie)); if (V0_ENCODING_COOKIE != encoding_cookie) { FAIL_AND_CLEANUP(cleanup, result, HDR_ENCODING_COOKIE_MISMATCH); } int32_t word_size = word_size_from_cookie(be32toh(encoding_flyweight.cookie)); int64_t lowest_trackable_value = be64toh(encoding_flyweight.lowest_trackable_value); int64_t highest_trackable_value = be64toh(encoding_flyweight.highest_trackable_value); int32_t significant_figures = be32toh(encoding_flyweight.significant_figures); if (hdr_init( lowest_trackable_value, highest_trackable_value, significant_figures, &h) != 0) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } int32_t counts_array_len = h->counts_len * word_size; if ((counts_array = calloc(1, (size_t) counts_array_len)) == NULL) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } strm.next_out = counts_array; strm.avail_out = (uInt) counts_array_len; if (inflate(&strm, Z_FINISH) != Z_STREAM_END) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } _apply_to_counts(h, word_size, counts_array, h->counts_len); hdr_reset_internal_counters(h); h->normalizing_index_offset = 0; h->conversion_ratio = 1.0; cleanup: (void)inflateEnd(&strm); free(counts_array); if (result != 0) { free(h); } else if (NULL == *histogram) { *histogram = h; } else { hdr_add(*histogram, h); free(h); } return result; } static int hdr_decode_compressed_v1( _compression_flyweight* compression_flyweight, size_t length, struct hdr_histogram** histogram) { struct hdr_histogram* h = NULL; int result = 0; uint8_t* counts_array = NULL; _encoding_flyweight_v1 encoding_flyweight; z_stream strm; strm_init(&strm); if (inflateInit(&strm) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t compressed_length = be32toh(compression_flyweight->length); if (compressed_length < 0 || length - sizeof(_compression_flyweight) < (size_t)compressed_length) { FAIL_AND_CLEANUP(cleanup, result, EINVAL); } strm.next_in = compression_flyweight->data; strm.avail_in = (uInt) compressed_length; strm.next_out = (uint8_t *) &encoding_flyweight; strm.avail_out = sizeof(_encoding_flyweight_v1); if (inflate(&strm, Z_SYNC_FLUSH) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t encoding_cookie = get_cookie_base(be32toh(encoding_flyweight.cookie)); if (V1_ENCODING_COOKIE != encoding_cookie) { FAIL_AND_CLEANUP(cleanup, result, HDR_ENCODING_COOKIE_MISMATCH); } int32_t word_size = word_size_from_cookie(be32toh(encoding_flyweight.cookie)); int32_t counts_limit = be32toh(encoding_flyweight.payload_len) / word_size; int64_t lowest_trackable_value = be64toh(encoding_flyweight.lowest_trackable_value); int64_t highest_trackable_value = be64toh(encoding_flyweight.highest_trackable_value); int32_t significant_figures = be32toh(encoding_flyweight.significant_figures); if (hdr_init( lowest_trackable_value, highest_trackable_value, significant_figures, &h) != 0) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } // Give the temp uncompressed array a little bif of extra int32_t counts_array_len = counts_limit * word_size; if ((counts_array = calloc(1, (size_t) counts_array_len)) == NULL) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } strm.next_out = counts_array; strm.avail_out = (uInt) counts_array_len; if (inflate(&strm, Z_FINISH) != Z_STREAM_END) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } _apply_to_counts(h, word_size, counts_array, counts_limit); h->normalizing_index_offset = be32toh(encoding_flyweight.normalizing_index_offset); h->conversion_ratio = int64_bits_to_double(be64toh(encoding_flyweight.conversion_ratio_bits)); hdr_reset_internal_counters(h); cleanup: (void)inflateEnd(&strm); free(counts_array); if (result != 0) { free(h); } else if (NULL == *histogram) { *histogram = h; } else { hdr_add(*histogram, h); free(h); } return result; } static int hdr_decode_compressed_v2( _compression_flyweight* compression_flyweight, size_t length, struct hdr_histogram** histogram) { struct hdr_histogram* h = NULL; int result = 0; uint8_t* counts_array = NULL; _encoding_flyweight_v1 encoding_flyweight; z_stream strm; strm_init(&strm); if (inflateInit(&strm) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t compressed_length = be32toh(compression_flyweight->length); if (compressed_length < 0 || length - sizeof(_compression_flyweight) < (size_t)compressed_length) { FAIL_AND_CLEANUP(cleanup, result, EINVAL); } strm.next_in = compression_flyweight->data; strm.avail_in = (uInt) compressed_length; strm.next_out = (uint8_t *) &encoding_flyweight; strm.avail_out = sizeof(_encoding_flyweight_v1); if (inflate(&strm, Z_SYNC_FLUSH) != Z_OK) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int32_t encoding_cookie = get_cookie_base(be32toh(encoding_flyweight.cookie)); if (V2_ENCODING_COOKIE != encoding_cookie) { FAIL_AND_CLEANUP(cleanup, result, HDR_ENCODING_COOKIE_MISMATCH); } int32_t counts_limit = be32toh(encoding_flyweight.payload_len); int64_t lowest_trackable_value = be64toh(encoding_flyweight.lowest_trackable_value); int64_t highest_trackable_value = be64toh(encoding_flyweight.highest_trackable_value); int32_t significant_figures = be32toh(encoding_flyweight.significant_figures); if (hdr_init( lowest_trackable_value, highest_trackable_value, significant_figures, &h) != 0) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } // Make sure there at least 9 bytes to read // if there is a corrupt value at the end // of the array we won't read corrupt data or crash. if ((counts_array = calloc(1, (size_t) counts_limit + 9)) == NULL) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } strm.next_out = counts_array; strm.avail_out = (uInt) counts_limit; if (inflate(&strm, Z_FINISH) != Z_STREAM_END) { FAIL_AND_CLEANUP(cleanup, result, HDR_INFLATE_FAIL); } int r = _apply_to_counts_zz(h, counts_array, counts_limit); if (0 != r) { FAIL_AND_CLEANUP(cleanup, result, r); } h->normalizing_index_offset = be32toh(encoding_flyweight.normalizing_index_offset); h->conversion_ratio = int64_bits_to_double(be64toh(encoding_flyweight.conversion_ratio_bits)); hdr_reset_internal_counters(h); cleanup: (void)inflateEnd(&strm); free(counts_array); if (result != 0) { free(h); } else if (NULL == *histogram) { *histogram = h; } else { hdr_add(*histogram, h); free(h); } return result; } int hdr_decode_compressed( uint8_t* buffer, size_t length, struct hdr_histogram** histogram) { if (length < sizeof(_compression_flyweight)) { return EINVAL; } _compression_flyweight* compression_flyweight = (_compression_flyweight*) buffer; int32_t compression_cookie = get_cookie_base(be32toh(compression_flyweight->cookie)); if (V0_COMPRESSION_COOKIE == compression_cookie) { return hdr_decode_compressed_v0(compression_flyweight, length, histogram); } else if (V1_COMPRESSION_COOKIE == compression_cookie) { return hdr_decode_compressed_v1(compression_flyweight, length, histogram); } else if (V2_COMPRESSION_COOKIE == compression_cookie) { return hdr_decode_compressed_v2(compression_flyweight, length, histogram); } return HDR_COMPRESSION_COOKIE_MISMATCH; } // ## ## ######## #### ######## ######## ######## // ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## // ## ## ## ######## ## ## ###### ######## // ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## // ### ### ## ## #### ## ######## ## ## int hdr_log_writer_init(struct hdr_log_writer* writer) { (void)writer; return 0; } #define LOG_VERSION "1.2" #define LOG_MAJOR_VERSION 1 static int print_user_prefix(FILE* f, const char* prefix) { if (!prefix) { return 0; } return fprintf(f, "#[%s]\n", prefix); } static int print_version(FILE* f, const char* version) { return fprintf(f, "#[Histogram log format version %s]\n", version); } static int print_time(FILE* f, struct timespec* timestamp) { char time_str[128]; struct tm date_time; if (!timestamp) { return 0; } gmtime_r(×tamp->tv_sec, &date_time); long ms = timestamp->tv_nsec / 1000000; strftime(time_str, 128, "%a %b %X %Z %Y", &date_time); return fprintf( f, "#[StartTime: %d.%ld (seconds since epoch), %s]\n", (int) timestamp->tv_sec, ms, time_str); } static int print_header(FILE* f) { return fprintf(f, "\"StartTimestamp\",\"EndTimestamp\",\"Interval_Max\",\"Interval_Compressed_Histogram\"\n"); } // Example log // #[Logged with jHiccup version 2.0.3-SNAPSHOT] // #[Histogram log format version 1.01] // #[StartTime: 1403476110.183 (seconds since epoch), Mon Jun 23 10:28:30 NZST 2014] // "StartTimestamp","EndTimestamp","Interval_Max","Interval_Compressed_Histogram" int hdr_log_write_header( struct hdr_log_writer* writer, FILE* file, const char* user_prefix, struct timespec* timestamp) { (void)writer; if (print_user_prefix(file, user_prefix) < 0) { return EIO; } if (print_version(file, LOG_VERSION) < 0) { return EIO; } if (print_time(file, timestamp) < 0) { return EIO; } if (print_header(file) < 0) { return EIO; } return 0; } int hdr_log_write( struct hdr_log_writer* writer, FILE* file, const struct timespec* start_timestamp, const struct timespec* end_timestamp, struct hdr_histogram* histogram) { uint8_t* compressed_histogram = NULL; size_t compressed_len = 0; char* encoded_histogram = NULL; int rc = 0; int result = 0; size_t encoded_len; (void)writer; rc = hdr_encode_compressed(histogram, &compressed_histogram, &compressed_len); if (rc != 0) { FAIL_AND_CLEANUP(cleanup, result, rc); } encoded_len = hdr_base64_encoded_len(compressed_len); encoded_histogram = calloc(encoded_len + 1, sizeof(char)); rc = hdr_base64_encode( compressed_histogram, compressed_len, encoded_histogram, encoded_len); if (rc != 0) { FAIL_AND_CLEANUP(cleanup, result, rc); } if (fprintf( file, "%d.%d,%d.%d,%"PRIu64".0,%s\n", (int) start_timestamp->tv_sec, (int) (start_timestamp->tv_nsec / 1000000), (int) end_timestamp->tv_sec, (int) (end_timestamp->tv_nsec / 1000000), hdr_max(histogram), encoded_histogram) < 0) { result = EIO; } cleanup: free(compressed_histogram); free(encoded_histogram); return result; } // ######## ######## ### ######## ######## ######## // ## ## ## ## ## ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## // ######## ###### ## ## ## ## ###### ######## // ## ## ## ######### ## ## ## ## ## // ## ## ## ## ## ## ## ## ## ## // ## ## ######## ## ## ######## ######## ## ## int hdr_log_reader_init(struct hdr_log_reader* reader) { reader->major_version = 0; reader->minor_version = 0; reader->start_timestamp.tv_sec = 0; reader->start_timestamp.tv_nsec = 0; return 0; } static void scan_log_format(struct hdr_log_reader* reader, const char* line) { const char* format = "#[Histogram log format version %d.%d]"; sscanf(line, format, &reader->major_version, &reader->minor_version); } static void scan_start_time(struct hdr_log_reader* reader, const char* line) { const char* format = "#[StartTime: %d.%d [^\n]"; int timestamp_s = 0; int trailing_ms = 0; if (sscanf(line, format, ×tamp_s, &trailing_ms) == 2) { reader->start_timestamp.tv_sec = timestamp_s; reader->start_timestamp.tv_nsec = trailing_ms * 1000000; } } static void scan_header_line(struct hdr_log_reader* reader, const char* line) { scan_log_format(reader, line); scan_start_time(reader, line); } static bool validate_log_version(struct hdr_log_reader* reader) { return reader->major_version == LOG_MAJOR_VERSION && (reader->minor_version == 0 || reader->minor_version == 1 || reader->minor_version == 2); } #define HEADER_LINE_LENGTH 128 int hdr_log_read_header(struct hdr_log_reader* reader, FILE* file) { char line[HEADER_LINE_LENGTH]; // TODO: check for overflow. bool parsing_header = true; do { int c = fgetc(file); ungetc(c, file); switch (c) { case '#': if (fgets(line, HEADER_LINE_LENGTH, file) == NULL) { return EIO; } scan_header_line(reader, line); break; case '"': if (fgets(line, HEADER_LINE_LENGTH, file) == NULL) { return EIO; } parsing_header = false; break; default: parsing_header = false; } } while (parsing_header); if (!validate_log_version(reader)) { return HDR_LOG_INVALID_VERSION; } return 0; } static void update_timespec(struct timespec* ts, int time_s, int time_ms) { if (NULL == ts) { return; } ts->tv_sec = time_s; ts->tv_nsec = time_ms * 1000000; } int hdr_log_read( struct hdr_log_reader* reader, FILE* file, struct hdr_histogram** histogram, struct timespec* timestamp, struct timespec* interval) { const char* format = "%d.%d,%d.%d,%d.%d,%s"; char* base64_histogram = NULL; uint8_t* compressed_histogram = NULL; char* line = NULL; size_t line_len = 0; int result = 0; int begin_s = 0; int begin_ms = 0; int end_s = 0; int end_ms = 0; int interval_max_s = 0; int interval_max_ms = 0; (void)reader; ssize_t read = getline(&line, &line_len, file); if (-1 == read) { if (0 == errno) { FAIL_AND_CLEANUP(cleanup, result, EOF); } else { FAIL_AND_CLEANUP(cleanup, result, EIO); } } null_trailing_whitespace(line, read); if (strlen(line) == 0) { FAIL_AND_CLEANUP(cleanup, result, EOF); } int r; r = realloc_buffer((void**)&base64_histogram, sizeof(char), read); if (r != 0) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } r = realloc_buffer((void**)&compressed_histogram, sizeof(uint8_t), read); if (r != 0) { FAIL_AND_CLEANUP(cleanup, result, ENOMEM); } int num_tokens = sscanf( line, format, &begin_s, &begin_ms, &end_s, &end_ms, &interval_max_s, &interval_max_ms, base64_histogram); if (num_tokens != 7) { FAIL_AND_CLEANUP(cleanup, result, EINVAL); } size_t base64_len = strlen(base64_histogram); size_t compressed_len = hdr_base64_decoded_len(base64_len); r = hdr_base64_decode( base64_histogram, base64_len, compressed_histogram, compressed_len); if (r != 0) { FAIL_AND_CLEANUP(cleanup, result, r); } r = hdr_decode_compressed(compressed_histogram, compressed_len, histogram); if (r != 0) { FAIL_AND_CLEANUP(cleanup, result, r); } update_timespec(timestamp, begin_s, begin_ms); update_timespec(interval, end_s, end_ms); cleanup: free(line); free(base64_histogram); free(compressed_histogram); return result; } int hdr_log_encode(struct hdr_histogram* histogram, char** encoded_histogram) { char *encoded_histogram_tmp = NULL; uint8_t* compressed_histogram = NULL; size_t compressed_len = 0; int rc = 0; int result = 0; size_t encoded_len; rc = hdr_encode_compressed(histogram, &compressed_histogram, &compressed_len); if (rc != 0) { FAIL_AND_CLEANUP(cleanup, result, rc); } encoded_len = hdr_base64_encoded_len(compressed_len); encoded_histogram_tmp = calloc(encoded_len + 1, sizeof(char)); rc = hdr_base64_encode( compressed_histogram, compressed_len, encoded_histogram_tmp, encoded_len); if (rc != 0) { FAIL_AND_CLEANUP(cleanup, result, rc); } *encoded_histogram = encoded_histogram_tmp; cleanup: free(compressed_histogram); return result; } int hdr_log_decode(struct hdr_histogram** histogram, char* base64_histogram, size_t base64_len) { int r; uint8_t* compressed_histogram = NULL; int result = 0; size_t compressed_len = hdr_base64_decoded_len(base64_len); compressed_histogram = malloc(sizeof(uint8_t)*compressed_len); memset(compressed_histogram, 0, compressed_len); r = hdr_base64_decode( base64_histogram, base64_len, compressed_histogram, compressed_len); if (r != 0) { FAIL_AND_CLEANUP(cleanup, result, r); } r = hdr_decode_compressed(compressed_histogram, compressed_len, histogram); if (r != 0) { FAIL_AND_CLEANUP(cleanup, result, r); } cleanup: free(compressed_histogram); return result; } diskscan-0.21/hdrhistogram/src/hdr_histogram_log.h000066400000000000000000000131201456470715000223670ustar00rootroot00000000000000/** * hdr_histogram_log.h * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ * * The implementation makes use of zlib to provide compression. You will need * to link against -lz in order to link applications that include this header. */ #ifndef HDR_HISTOGRAM_H_LOG #define HDR_HISTOGRAM_H_LOG 1 #define HDR_COMPRESSION_COOKIE_MISMATCH -29999 #define HDR_ENCODING_COOKIE_MISMATCH -29998 #define HDR_DEFLATE_INIT_FAIL -29997 #define HDR_DEFLATE_FAIL -29996 #define HDR_INFLATE_INIT_FAIL -29995 #define HDR_INFLATE_FAIL -29994 #define HDR_LOG_INVALID_VERSION -29993 #define HDR_TRAILING_ZEROS_INVALID -29992 #define HDR_VALUE_TRUNCATED -29991 #define HDR_ENCODED_INPUT_TOO_LONG -29990 #include #include #include #include #include "hdr_histogram.h" /** * Encode and compress the histogram with gzip. */ int hdr_log_encode(struct hdr_histogram* histogram, char** encoded_histogram); /** * Decode and decompress the histogram with gzip. */ int hdr_log_decode(struct hdr_histogram** histogram, char* base64_histogram, size_t base64_len); struct hdr_log_writer { }; /** * Initialise the log writer. * * @param writer 'This' pointer * @return 0 on success. */ int hdr_log_writer_init(struct hdr_log_writer* writer); /** * Write the header to the log, this will constist of a user defined string, * the current timestamp, version information and the CSV header. * * @param writer 'This' pointer * @param file The stream to output the log header to. * @param user_prefix User defined string to include in the header. * @param timestamp The start time that the histogram started recording from. * @return Will return 0 if it successfully completed or an error number if there * was a failure. EIO if the write failed. */ int hdr_log_write_header( struct hdr_log_writer* writer, FILE* file, const char* user_prefix, struct timespec* timestamp); /** * Write an hdr_histogram entry to the log. It will be encoded in a similar * fashion to the approach used by the Java version of the HdrHistogram. It will * be a CSV line consisting of ,,, * where is the binary histogram gzip compressed and base64 encoded. * * Timestamp is a bit of misnomer for the start_timestamp and end_timestamp values * these could be offsets, e.g. start_timestamp could be offset from process start * time and end_timestamp could actually be the length of the recorded interval. * * @param writer 'This' pointer * @param file The stream to write the entry to. * @param start_timestamp The start timestamp to include in the logged entry. * @param end_timestamp The end timestamp to include in the logged entry. * @param histogram The histogram to encode and log. * @return Will return 0 if it successfully completed or an error number if there * was a failure. Errors include HDR_DEFLATE_INIT_FAIL, HDR_DEFLATE_FAIL if * something when wrong during gzip compression. ENOMEM if we failed to allocate * or reallocate the buffer used for encoding (out of memory problem). EIO if * write failed. */ int hdr_log_write( struct hdr_log_writer* writer, FILE* file, const struct timespec* start_timestamp, const struct timespec* end_timestamp, struct hdr_histogram* histogram); struct hdr_log_reader { int major_version; int minor_version; struct timespec start_timestamp; }; /** * Initialise the log reader. * * @param reader 'This' pointer * @return 0 on success */ int hdr_log_reader_init(struct hdr_log_reader* reader); /** * Reads the the header information from the log. Will capure information * such as version number and start timestamp from the header. * * @param hdr_log_reader 'This' pointer * @param file The data stream to read from. * @return 0 on success. An error number on failure. */ int hdr_log_read_header(struct hdr_log_reader* reader, FILE* file); /** * Reads an entry from the log filling in the specified histogram, timestamp and * interval values. If the supplied pointer to the histogram for this method is * NULL then a new histogram will be allocated for the caller, however it will * become the callers responsibility to free it later. If the pointer is non-null * the histogram read from the log will be merged with the supplied histogram. * * @param reader 'This' pointer * @param file The stream to read the histogram from. * @param histogram Pointer to allocate a histogram to or merge into. * @param timestamp The first timestamp from the CSV entry. * @param interval The second timestamp from the CSV entry * @return Will return 0 on success or an error number if there was some wrong * when reading in the histogram. EOF (-1) will indicate that there are no more * histograms left to be read from 'file'. * HDR_INFLATE_INIT_FAIL or HDR_INFLATE_FAIL if * there was a problem with Gzip. HDR_COMPRESSION_COOKIE_MISMATCH or * HDR_ENCODING_COOKIE_MISMATCH if the cookie values are incorrect. * HDR_LOG_INVALID_VERSION if the log can not be parsed. ENOMEM if buffer space * or the histogram can not be allocated. EIO if there was an error during * the read. EINVAL in any input values are incorrect. */ int hdr_log_read( struct hdr_log_reader* reader, FILE* file, struct hdr_histogram** histogram, struct timespec* timestamp, struct timespec* interval); /** * Returns a string representation of the error number. * * @param errnum The error response from a previous call. * @return The user readable representation of the error. */ const char* hdr_strerror(int errnum); #endif diskscan-0.21/hdrhistogram/src/hdr_interval_recorder.c000066400000000000000000000023031456470715000232360ustar00rootroot00000000000000/** * hdr_interval_recorder.h * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include "hdr_interval_recorder.h" int hdr_interval_recorder_init(struct hdr_interval_recorder* r) { return hdr_writer_reader_phaser_init(&r->phaser); } void hdr_interval_recorder_destroy(struct hdr_interval_recorder* r) { hdr_writer_reader_phaser_destory(&r->phaser); } void hdr_interval_recorder_update( struct hdr_interval_recorder* r, void(*update_action)(void*, void*), void* arg) { int64_t val = hdr_phaser_writer_enter(&r->phaser); void* active = __atomic_load_n(&r->active, __ATOMIC_SEQ_CST); update_action(active, arg); hdr_phaser_writer_exit(&r->phaser, val); } void* hdr_interval_recorder_sample(struct hdr_interval_recorder* r) { void* temp; hdr_phaser_reader_lock(&r->phaser); temp = r->inactive; // volatile read r->inactive = __atomic_load_n(&r->active, __ATOMIC_SEQ_CST); // volatile write __atomic_store_n(&r->active, temp, __ATOMIC_SEQ_CST); hdr_phaser_flip_phase(&r->phaser, 0); hdr_phaser_reader_unlock(&r->phaser); return r->inactive; } diskscan-0.21/hdrhistogram/src/hdr_interval_recorder.h000066400000000000000000000013751456470715000232530ustar00rootroot00000000000000/** * hdr_interval_recorder.h * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #ifndef HDR_INTERVAL_RECORDER_H #define HDR_INTERVAL_RECORDER_H 1 #include "hdr_writer_reader_phaser.h" struct hdr_interval_recorder { void* active; void* inactive; struct hdr_writer_reader_phaser phaser; } __attribute__((aligned (8))); int hdr_interval_recorder_init(struct hdr_interval_recorder* r); void hdr_interval_recorder_destroy(struct hdr_interval_recorder* r); void hdr_interval_recorder_update( struct hdr_interval_recorder* r, void(*update_action)(void*, void*), void* arg); void* hdr_interval_recorder_sample(struct hdr_interval_recorder* r); #endif diskscan-0.21/hdrhistogram/src/hdr_tests.h000066400000000000000000000011551456470715000207000ustar00rootroot00000000000000#ifndef HDR_TESTS_H #define HDR_TESTS_H /* These are functions used in tests and are not intended for normal usage. */ #include "hdr_histogram.h" void hdr_reset_internal_counters(struct hdr_histogram* h); int32_t counts_index_for(const struct hdr_histogram* h, int64_t value); int hdr_encode_compressed(struct hdr_histogram* h, uint8_t** compressed_histogram, size_t* compressed_len); int hdr_decode_compressed(uint8_t* buffer, size_t length, struct hdr_histogram** histogram); void hdr_base64_decode_block(const char* input, uint8_t* output); void hdr_base64_encode_block(const uint8_t* input, char* output); #endif diskscan-0.21/hdrhistogram/src/hdr_time.h000066400000000000000000000013301456470715000204670ustar00rootroot00000000000000/** * hdr_time.h * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #if defined(__APPLE__) #include #include static void hdr_gettime(struct timespec* ts) { clock_serv_t cclock; mach_timespec_t mts; host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock); clock_get_time(cclock, &mts); mach_port_deallocate(mach_task_self(), cclock); ts->tv_sec = mts.tv_sec; ts->tv_nsec = mts.tv_nsec; } #elif defined(__linux__) static void hdr_gettime(struct timespec* t) { clock_gettime(CLOCK_MONOTONIC, t); } #else #warning "Platform not supported\n" #endif diskscan-0.21/hdrhistogram/src/hdr_writer_reader_phaser.c000066400000000000000000000062371456470715000237370ustar00rootroot00000000000000/** * hdr_writer_reader_phaser.h * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #include #include #include #include #include #include #include "hdr_writer_reader_phaser.h" static int64_t _hdr_phaser_get_epoch(int64_t* field) { return __atomic_load_n(field, __ATOMIC_SEQ_CST); } static void _hdr_phaser_set_epoch(int64_t* field, int64_t val) { __atomic_store_n(field, val, __ATOMIC_SEQ_CST); } static int64_t _hdr_phaser_reset_epoch(int64_t* field, int64_t initial_value) { return __atomic_exchange_n(field, initial_value, __ATOMIC_SEQ_CST); } int hdr_writer_reader_phaser_init(struct hdr_writer_reader_phaser* p) { if (NULL == p) { return EINVAL; } p->start_epoch = 0; p->even_end_epoch = 0; p->odd_end_epoch = INT64_MIN; p->reader_mutex = malloc(sizeof(pthread_mutex_t)); if (!p->reader_mutex) { return ENOMEM; } int rc = pthread_mutex_init(p->reader_mutex, NULL); if (0 != rc) { return rc; } // TODO: Should I fence here. return 0; } void hdr_writer_reader_phaser_destory(struct hdr_writer_reader_phaser* p) { pthread_mutex_destroy(p->reader_mutex); } int64_t hdr_phaser_writer_enter(struct hdr_writer_reader_phaser* p) { return __atomic_add_fetch(&p->start_epoch, 1, __ATOMIC_SEQ_CST); } void hdr_phaser_writer_exit( struct hdr_writer_reader_phaser* p, int64_t critical_value_at_enter) { int64_t* end_epoch = (critical_value_at_enter < 0) ? &p->odd_end_epoch : &p->even_end_epoch; __atomic_add_fetch(end_epoch, 1, __ATOMIC_SEQ_CST); } void hdr_phaser_reader_lock(struct hdr_writer_reader_phaser* p) { pthread_mutex_lock(p->reader_mutex); } void hdr_phaser_reader_unlock(struct hdr_writer_reader_phaser* p) { pthread_mutex_unlock(p->reader_mutex); } void hdr_phaser_flip_phase( struct hdr_writer_reader_phaser* p, int64_t sleep_time_ns) { // TODO: is_held_by_current_thread int64_t start_epoch = _hdr_phaser_get_epoch(&p->start_epoch); bool next_phase_is_even = (start_epoch < 0); // Clear currently used phase end epoch. int64_t initial_start_value; if (next_phase_is_even) { initial_start_value = 0; _hdr_phaser_set_epoch(&p->even_end_epoch, initial_start_value); } else { initial_start_value = INT64_MIN; _hdr_phaser_set_epoch(&p->odd_end_epoch, initial_start_value); } // Reset start value, indicating new phase. int64_t start_value_at_flip = _hdr_phaser_reset_epoch(&p->start_epoch, initial_start_value); bool caught_up = false; do { int64_t* end_epoch = next_phase_is_even ? &p->odd_end_epoch : &p->even_end_epoch; caught_up = _hdr_phaser_get_epoch(end_epoch) == start_value_at_flip; if (!caught_up) { if (sleep_time_ns == 0) { sched_yield(); } else { usleep(sleep_time_ns / 1000); } } } while (!caught_up); } diskscan-0.21/hdrhistogram/src/hdr_writer_reader_phaser.h000066400000000000000000000021201456470715000237270ustar00rootroot00000000000000/** * hdr_writer_reader_phaser.h * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #ifndef HDR_WRITER_READER_PHASER_H #define HDR_WRITER_READER_PHASER_H 1 #include #include #include #include #include #include struct hdr_writer_reader_phaser { int64_t start_epoch; int64_t even_end_epoch; int64_t odd_end_epoch; pthread_mutex_t* reader_mutex; } __attribute__((aligned (8))); int hdr_writer_reader_phaser_init(struct hdr_writer_reader_phaser* p); void hdr_writer_reader_phaser_destory(struct hdr_writer_reader_phaser* p); int64_t hdr_phaser_writer_enter(struct hdr_writer_reader_phaser* p); void hdr_phaser_writer_exit( struct hdr_writer_reader_phaser* p, int64_t critical_value_at_enter); void hdr_phaser_reader_lock(struct hdr_writer_reader_phaser* p); void hdr_phaser_reader_unlock(struct hdr_writer_reader_phaser* p); void hdr_phaser_flip_phase( struct hdr_writer_reader_phaser* p, int64_t sleep_time_ns); #endifdiskscan-0.21/hdrhistogram/test/000077500000000000000000000000001456470715000167165ustar00rootroot00000000000000diskscan-0.21/hdrhistogram/test/CMakeLists.txt000066400000000000000000000017701456470715000214630ustar00rootroot00000000000000INCLUDE(CheckLibraryExists) add_executable(hdr_histogram_test hdr_histogram_test.c) add_executable(hdr_histogram_log_test hdr_histogram_log_test.c) add_executable(perftest hdr_histogram_perf.c) target_link_libraries(hdr_histogram_test hdr_histogram m) target_link_libraries(hdr_histogram_log_test hdr_histogram m z) target_link_libraries(perftest hdr_histogram m z) CHECK_LIBRARY_EXISTS(rt clock_gettime "" RT_EXISTS) if (RT_EXISTS) target_link_libraries(hdr_histogram_log_test rt) target_link_libraries(perftest rt) endif (RT_EXISTS) install(TARGETS hdr_histogram_test DESTINATION bin) install(TARGETS hdr_histogram_log_test DESTINATION bin) install(TARGETS perftest DESTINATION bin) add_test(Histogram hdr_histogram_test) add_test(HistogramLogging hdr_histogram_log_test) configure_file(jHiccup-2.0.1.logV0.hlog jHiccup-2.0.1.logV0.hlog COPYONLY) configure_file(jHiccup-2.0.6.logV1.hlog jHiccup-2.0.6.logV1.hlog COPYONLY) configure_file(jHiccup-2.0.7S.logV2.hlog jHiccup-2.0.7S.logV2.hlog COPYONLY) diskscan-0.21/hdrhistogram/test/hdr_histogram_log_test.c000066400000000000000000000557201456470715000236250ustar00rootroot00000000000000/** * hdr_histogram_log_test.c * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #include #include #include #include #include #include #include #include #include "hdr_time.h" #include #include #include #include "minunit.h" int tests_run = 0; static bool compare_int(int a, int b) { if (a == b) { return true; } printf("%d != %d\n", a, b); return false; } static long ns_to_ms(long ns) { return (ns / 1000000) * 1000000; } static bool compare_timespec(struct timespec* a, struct timespec* b) { char a_str[128]; char b_str[128]; long a_tv_msec = ns_to_ms(a->tv_nsec); long b_tv_msec = ns_to_ms(b->tv_nsec); if (a->tv_sec == a->tv_sec && a_tv_msec == b_tv_msec) { return true; } if (a->tv_sec != b->tv_sec) { printf( "tv_sec: %s != %s\n", ctime_r(&a->tv_sec, a_str), ctime_r(&b->tv_sec, b_str)); } if (a_tv_msec == b_tv_msec) { printf("%ld != %ld\n", a->tv_nsec, b->tv_nsec); } return false; } static bool compare_string(const char* a, const char* b, int len) { if (strncmp(a, b, len) == 0) { return true; } printf("%s != %s\n", a, b); return false; } static bool compare_histogram(struct hdr_histogram* a, struct hdr_histogram* b) { if (a->counts_len != b->counts_len) { printf( "a.counts_len = %"PRIu32", b.counts_len = %"PRIu32"\n", a->counts_len, b->counts_len); return false; } int64_t a_max = hdr_max(a); int64_t b_max = hdr_max(b); if (a_max != b_max) { printf("a.max = %"PRIu64", b.max = %"PRIu64"\n", a_max, b_max); // return false; } int64_t a_min = hdr_min(a); int64_t b_min = hdr_min(b); if (a_min != b_min) { printf("a.min = %"PRIu64", b.min = %"PRIu64"\n", a_min, b_min); // return false; } size_t a_size = hdr_get_memory_size(a); size_t b_size = hdr_get_memory_size(b); if (a_size != b_size) { printf("a.size: %zu, b.size: %zu\n", a_size, b_size); return false; } size_t counts_size = a->counts_len * sizeof(int64_t); if (memcmp(a->counts, b->counts, counts_size) == 0) { return true; } printf("%s\n", "Counts incorrect"); struct hdr_iter iter_a; struct hdr_iter iter_b; hdr_iter_init(&iter_a, a); hdr_iter_init(&iter_b, b); while (hdr_iter_next(&iter_a) && hdr_iter_next(&iter_b)) { if (iter_a.count != iter_b.count || iter_a.value != iter_b.value) { printf( "A - value: %"PRIu64", count: %"PRIu64", B - value: %"PRIu64", count: %"PRIu64"\n", iter_a.value, iter_a.count, iter_b.value, iter_b.count); } } return false; } static struct hdr_histogram* raw_histogram = NULL; static struct hdr_histogram* cor_histogram = NULL; static void load_histograms() { free(raw_histogram); free(cor_histogram); hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &raw_histogram); hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &cor_histogram); int i; for (i = 0; i < 10000; i++) { hdr_record_value(raw_histogram, 1000); hdr_record_corrected_value(cor_histogram, 1000, 10000); } hdr_record_value(raw_histogram, 100000000); hdr_record_corrected_value(cor_histogram, 100000000, 10000); } static bool validate_return_code(int rc) { if (rc == 0) { return true; } printf("%s\n", hdr_strerror(rc)); return false; } // Prototypes to avoid exporting in header file. void hdr_base64_encode_block(const uint8_t* input, char* output); void hdr_base64_decode_block(const char* input, uint8_t* output); int hdr_encode_compressed(struct hdr_histogram* h, uint8_t** buffer, size_t* length); int hdr_decode_compressed( uint8_t* buffer, size_t length, struct hdr_histogram** histogram); void hex_dump (char *desc, void *addr, int len); static char* test_encode_and_decode_compressed() { load_histograms(); uint8_t* buffer = NULL; size_t len = 0; int rc = 0; struct hdr_histogram* actual = NULL; struct hdr_histogram* expected = raw_histogram; rc = hdr_encode_compressed(expected, &buffer, &len); mu_assert("Did not encode", validate_return_code(rc)); rc = hdr_decode_compressed(buffer, len, &actual); mu_assert("Did not decode", validate_return_code(rc)); mu_assert("Loaded histogram is null", actual != NULL); mu_assert( "Comparison did not match", compare_histogram(expected, actual)); free(actual); return 0; } static char* test_encode_and_decode_compressed2() { load_histograms(); uint8_t* buffer = NULL; size_t len = 0; int rc = 0; struct hdr_histogram* actual = NULL; struct hdr_histogram* expected = cor_histogram; rc = hdr_encode_compressed(expected, &buffer, &len); mu_assert("Did not encode", validate_return_code(rc)); rc = hdr_decode_compressed(buffer, len, &actual); mu_assert("Did not decode", validate_return_code(rc)); mu_assert("Loaded histogram is null", actual != NULL); mu_assert( "Comparison did not match", compare_histogram(expected, actual)); free(actual); return 0; } static char* test_bounds_check_on_decode() { load_histograms(); uint8_t* buffer = NULL; size_t len = 0; int rc = 0; struct hdr_histogram* actual = NULL; struct hdr_histogram* expected = cor_histogram; rc = hdr_encode_compressed(expected, &buffer, &len); mu_assert("Did not encode", validate_return_code(rc)); rc = hdr_decode_compressed(buffer, len - 1, &actual); mu_assert("Should have be invalid", compare_int64(EINVAL, rc)); mu_assert("Should not have built histogram", NULL == actual); return 0; } static char* test_encode_and_decode_base64() { load_histograms(); uint8_t* buffer = NULL; uint8_t* decoded = NULL; char* encoded = NULL; size_t len = 0; int rc = 0; rc = hdr_encode_compressed(cor_histogram, &buffer, &len); mu_assert("Did not encode", validate_return_code(rc)); size_t encoded_len = hdr_base64_encoded_len(len); size_t decoded_len = hdr_base64_decoded_len(encoded_len); encoded = calloc(encoded_len + 1, sizeof(char)); decoded = calloc(decoded_len, sizeof(uint8_t)); hdr_base64_encode(buffer, len, encoded, encoded_len); hdr_base64_decode(encoded, encoded_len, decoded, decoded_len); mu_assert("Should be same", memcmp(buffer, decoded, len) == 0); return 0; } static char* test_encode_and_decode_compressed_large() { const int64_t limit = INT64_C(3600) * 1000 * 1000; struct hdr_histogram* actual = NULL; struct hdr_histogram* expected = NULL; uint8_t* buffer = NULL; size_t len = 0; int rc = 0; hdr_init(1, limit, 4, &expected); srand(5); int i; for (i = 0; i < 8070; i++) { hdr_record_value(expected, rand() % limit); } rc = hdr_encode_compressed(expected, &buffer, &len); mu_assert("Did not encode", validate_return_code(rc)); rc = hdr_decode_compressed(buffer, len, &actual); mu_assert("Did not decode", validate_return_code(rc)); mu_assert("Loaded histogram is null", actual != NULL); mu_assert( "Comparison did not match", compare_histogram(expected, actual)); free(expected); free(actual); return 0; } static bool assert_base64_encode(const char* input, const char* expected) { int input_len = strlen(input); int output_len = (int) (ceil(input_len / 3.0) * 4.0); char* output = calloc(sizeof(char), output_len); int r = hdr_base64_encode((uint8_t*)input, input_len, output, output_len); bool result = r == 0 && compare_string(expected, output, output_len); free(output); return result; } static char* base64_encode_encodes_without_padding() { mu_assert( "Encoding without padding", assert_base64_encode( "any carnal pleasur", "YW55IGNhcm5hbCBwbGVhc3Vy")); return 0; } static char* base64_encode_encodes_with_padding() { mu_assert( "Encoding with padding '='", assert_base64_encode( "any carnal pleasure.", "YW55IGNhcm5hbCBwbGVhc3VyZS4=")); mu_assert( "Encoding with padding '=='", assert_base64_encode( "any carnal pleasure", "YW55IGNhcm5hbCBwbGVhc3VyZQ==")); return 0; } static char* base64_encode_fails_with_invalid_lengths() { mu_assert( "Output length not 4/3 of input length", hdr_base64_encode(NULL, 9, NULL, 11)); return 0; } static char* base64_encode_block_encodes_3_bytes() { char output[5] = { 0 }; hdr_base64_encode_block((uint8_t*)"Man", output); mu_assert("Encoding", compare_string("TWFu", output, 4)); return 0; } static char* base64_decode_block_decodes_4_chars() { uint8_t output[4] = { 0 }; hdr_base64_decode_block("TWFu", output); mu_assert("Decoding", compare_string("Man", (char*) output, 3)); return 0; } static bool assert_base64_decode(const char* base64_encoded, const char* expected) { int encoded_len = strlen(base64_encoded); int output_len = (encoded_len / 4) * 3; uint8_t* output = calloc(sizeof(uint8_t), output_len); int result = hdr_base64_decode(base64_encoded, encoded_len, output, output_len); return result == 0 && compare_string(expected, (char*)output, output_len); } static char* base64_decode_decodes_strings_without_padding() { mu_assert( "Encoding without padding", assert_base64_decode( "YW55IGNhcm5hbCBwbGVhc3Vy", "any carnal pleasur")); return 0; } static char* base64_decode_decodes_strings_with_padding() { mu_assert( "Encoding with padding '='", assert_base64_decode( "YW55IGNhcm5hbCBwbGVhc3VyZS4=", "any carnal pleasure.")); mu_assert( "Encoding with padding '=='", assert_base64_decode( "YW55IGNhcm5hbCBwbGVhc3VyZQ==", "any carnal pleasure")); return 0; } static char* base64_decode_fails_with_invalid_lengths() { mu_assert("Input length % 4 != 0", hdr_base64_decode(NULL, 5, NULL, 3) != 0); mu_assert("Input length < 4", hdr_base64_decode(NULL, 3, NULL, 3) != 0); mu_assert( "Output length not 3/4 of input length", hdr_base64_decode(NULL, 8, NULL, 7) != 0); return 0; } static char* writes_and_reads_log() { const char* file_name = "histogram.log"; struct timespec timestamp; struct timespec interval; hdr_gettime(×tamp); interval.tv_sec = 5; interval.tv_nsec = 2000000; struct hdr_log_writer writer; struct hdr_log_reader reader; hdr_log_writer_init(&writer); hdr_log_reader_init(&reader); int rc = 0; FILE* log_file = fopen(file_name, "w+"); rc = hdr_log_write_header(&writer, log_file, "Test log", ×tamp); mu_assert("Failed header write", validate_return_code(rc)); hdr_log_write(&writer, log_file, ×tamp, &interval, cor_histogram); mu_assert("Failed corrected write", validate_return_code(rc)); hdr_log_write(&writer, log_file, ×tamp, &interval, raw_histogram); mu_assert("Failed raw write", validate_return_code(rc)); fprintf(log_file, "\n"); fflush(log_file); fclose(log_file); log_file = fopen(file_name, "r"); struct hdr_histogram* read_cor_histogram = NULL; struct hdr_histogram* read_raw_histogram = NULL; rc = hdr_log_read_header(&reader, log_file); mu_assert("Failed header read", validate_return_code(rc)); mu_assert("Incorrect major version", compare_int(reader.major_version, 1)); mu_assert("Incorrect minor version", compare_int(reader.minor_version, 2)); mu_assert( "Incorrect start timestamp", compare_timespec(&reader.start_timestamp, ×tamp)); struct timespec actual_timestamp; struct timespec actual_interval; rc = hdr_log_read( &reader, log_file, &read_cor_histogram, &actual_timestamp, &actual_interval); mu_assert("Failed corrected read", validate_return_code(rc)); mu_assert( "Incorrect first timestamp", compare_timespec(&actual_timestamp, ×tamp)); mu_assert( "Incorrect first interval", compare_timespec(&actual_interval, &interval)); rc = hdr_log_read(&reader, log_file, &read_raw_histogram, NULL, NULL); mu_assert("Failed raw read", validate_return_code(rc)); mu_assert( "Histograms do not match", compare_histogram(cor_histogram, read_cor_histogram)); mu_assert( "Histograms do not match", compare_histogram(raw_histogram, read_raw_histogram)); rc = hdr_log_read(&reader, log_file, &read_cor_histogram, NULL, NULL); mu_assert("No EOF at end of file", rc == EOF); fclose(log_file); remove(file_name); return 0; } static char* log_reader_aggregates_into_single_histogram() { const char* file_name = "histogram.log"; struct timespec timestamp; struct timespec interval; hdr_gettime(×tamp); interval.tv_sec = 5; interval.tv_nsec = 2000000; struct hdr_log_writer writer; struct hdr_log_reader reader; hdr_log_writer_init(&writer); hdr_log_reader_init(&reader); int rc = 0; FILE* log_file = fopen(file_name, "w+"); hdr_log_write_header(&writer, log_file, "Test log", ×tamp); hdr_log_write(&writer, log_file, ×tamp, &interval, cor_histogram); hdr_log_write(&writer, log_file, ×tamp, &interval, raw_histogram); fflush(log_file); fclose(log_file); log_file = fopen(file_name, "r"); struct hdr_histogram* histogram; hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &histogram); rc = hdr_log_read_header(&reader, log_file); mu_assert("Failed header read", validate_return_code(rc)); rc = hdr_log_read(&reader, log_file, &histogram, NULL, NULL); mu_assert("Failed corrected read", validate_return_code(rc)); rc = hdr_log_read(&reader, log_file, &histogram, NULL, NULL); mu_assert("Failed raw read", validate_return_code(rc)); struct hdr_iter iter; hdr_iter_recorded_init(&iter, histogram); int64_t expected_total_count = raw_histogram->total_count + cor_histogram->total_count; mu_assert( "Total counts incorrect", compare_int64(histogram->total_count, expected_total_count)); while (hdr_iter_next(&iter)) { int64_t count = iter.count; int64_t value = iter.value; int64_t expected_count = hdr_count_at_value(raw_histogram, value) + hdr_count_at_value(cor_histogram, value); mu_assert("Incorrect count", compare_int64(count, expected_count)); } fclose(log_file); remove(file_name); free(histogram); return 0; } static char* log_reader_fails_with_incorrect_version() { const char* log_with_invalid_version = "#[Test log]\n" "#[Histogram log format version 1.03]\n" "#[StartTime: 1404700005.222 (seconds since epoch), Mon Jul 02:26:45 GMT 2014]\n" "StartTimestamp\",\"EndTimestamp\",\"Interval_Max\",\"Interval_Compressed_Histogram\"\n"; const char* file_name = "histogram_with_invalid_version.log"; struct hdr_log_reader reader; FILE* log_file; log_file = fopen(file_name, "w+"); fprintf(log_file, "%s", log_with_invalid_version); fflush(log_file); fclose(log_file); log_file = fopen(file_name, "r"); hdr_log_reader_init(&reader); int r = hdr_log_read_header(&reader, log_file); mu_assert("Should error with incorrect version", r == HDR_LOG_INVALID_VERSION); fclose(log_file); remove(file_name); return 0; } static char* test_encode_decode_empty() { struct hdr_histogram *histogram, *hdr_new = NULL; hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &histogram); char *data; mu_assert("Failed to encode histogram data", hdr_log_encode(histogram, &data) == 0); mu_assert("Failed to decode histogram data", hdr_log_decode(&hdr_new, data, strlen(data)) == 0); mu_assert("Histograms should be the same", compare_histogram(histogram, hdr_new)); // mu_assert("Mean different after encode/decode", compare_double(hdr_mean(histogram), hdr_mean(hdr_new), 0.001)); free(histogram); free(hdr_new); free(data); return 0; } static char* test_string_encode_decode() { struct hdr_histogram *histogram, *hdr_new = NULL; hdr_alloc(INT64_C(3600) * 1000 * 1000, 3, &histogram); int i; for (i = 1; i < 100; i++) { hdr_record_value(histogram, i*i); } char *data; mu_assert("Failed to encode histogram data", hdr_log_encode(histogram, &data) == 0); mu_assert("Failed to decode histogram data", hdr_log_decode(&hdr_new, data, strlen(data)) == 0); mu_assert("Histograms should be the same", compare_histogram(histogram, hdr_new)); mu_assert("Mean different after encode/decode", compare_double(hdr_mean(histogram), hdr_mean(hdr_new), 0.001)); return 0; } static char* decode_v1_log() { const char* v1_log = "jHiccup-2.0.6.logV1.hlog"; FILE* f = fopen(v1_log, "r"); mu_assert("Can not open v1 log file", f != NULL); struct hdr_histogram* accum; hdr_init(1, INT64_C(3600000000000), 3, &accum); struct hdr_histogram* h = NULL; struct hdr_log_reader reader; struct timespec timestamp; struct timespec interval; hdr_log_reader_init(&reader); int rc = hdr_log_read_header(&reader, f); mu_assert("Failed to read header", rc == 0); int histogram_count = 0; int64_t total_count = 0; while ((rc = hdr_log_read(&reader, f, &h, ×tamp, &interval)) != EOF) { mu_assert("Failed to read histogram", rc == 0); histogram_count++; total_count += h->total_count; int64_t dropped = hdr_add(accum, h); mu_assert("Dropped events", compare_int64(dropped, 0)); free(h); h = NULL; } mu_assert("Wrong number of histograms", compare_int(histogram_count, 88)); mu_assert("Wrong total count", compare_int64(total_count, 65964)); mu_assert("99.9 percentile wrong", compare_int64(1829765119, hdr_value_at_percentile(accum, 99.9))); mu_assert("max value wrong", compare_int64(1888485375, hdr_max(accum))); mu_assert("Seconds wrong", compare_int64(1438867590, reader.start_timestamp.tv_sec)); mu_assert("Nanoseconds wrong", compare_int64(285000000, reader.start_timestamp.tv_nsec)); return 0; } static char* decode_v2_log() { const char* v2_log = "jHiccup-2.0.7S.logV2.hlog"; FILE* f = fopen(v2_log, "r"); mu_assert("Can not open v1 log file", f != NULL); struct hdr_histogram* accum; hdr_init(1, INT64_C(3600000000000), 3, &accum); struct hdr_histogram* h = NULL; struct hdr_log_reader reader; struct timespec timestamp; struct timespec interval; hdr_log_reader_init(&reader); int rc = hdr_log_read_header(&reader, f); mu_assert("Failed to read header", validate_return_code(rc)); int histogram_count = 0; int64_t total_count = 0; while ((rc = hdr_log_read(&reader, f, &h, ×tamp, &interval)) != EOF) { mu_assert("Failed to read histogram", validate_return_code(rc)); histogram_count++; total_count += h->total_count; int64_t dropped = hdr_add(accum, h); mu_assert("Dropped events", compare_int64(dropped, 0)); free(h); h = NULL; } mu_assert("Wrong number of histograms", compare_int(histogram_count, 62)); mu_assert("Wrong total count", compare_int64(total_count, 48761)); mu_assert("99.9 percentile wrong", compare_int64(1745879039, hdr_value_at_percentile(accum, 99.9))); mu_assert("max value wrong", compare_int64(1796210687, hdr_max(accum))); mu_assert("Seconds wrong", compare_int64(1441812279, reader.start_timestamp.tv_sec)); mu_assert("Nanoseconds wrong", compare_int64(474000000, reader.start_timestamp.tv_nsec)); return 0; } static char* decode_v0_log() { const char* v1_log = "jHiccup-2.0.1.logV0.hlog"; FILE* f = fopen(v1_log, "r"); mu_assert("Can not open v1 log file", f != NULL); struct hdr_histogram* accum; hdr_init(1, INT64_C(3600000000000), 3, &accum); struct hdr_histogram* h = NULL; struct hdr_log_reader reader; struct timespec timestamp; struct timespec interval; hdr_log_reader_init(&reader); int rc = hdr_log_read_header(&reader, f); mu_assert("Failed to read header", rc == 0); int histogram_count = 0; int64_t total_count = 0; while ((rc = hdr_log_read(&reader, f, &h, ×tamp, &interval)) != EOF) { mu_assert("Failed to read histogram", rc == 0); histogram_count++; total_count += h->total_count; int64_t dropped = hdr_add(accum, h); mu_assert("Dropped events", compare_int64(dropped, 0)); free(h); h = NULL; } mu_assert("Wrong number of histograms", compare_int(histogram_count, 81)); mu_assert("Wrong total count", compare_int64(total_count, 61256)); mu_assert("99.9 percentile wrong", compare_int64(1510998015, hdr_value_at_percentile(accum, 99.9))); mu_assert("max value wrong", compare_int64(1569718271, hdr_max(accum))); mu_assert("Seconds wrong", compare_int64(1438869961, reader.start_timestamp.tv_sec)); mu_assert("Nanoseconds wrong", compare_int64(225000000, reader.start_timestamp.tv_nsec)); return 0; } static struct mu_result all_tests() { tests_run = 0; mu_run_test(test_encode_decode_empty); mu_run_test(test_encode_and_decode_compressed); mu_run_test(test_encode_and_decode_compressed2); mu_run_test(test_encode_and_decode_compressed_large); mu_run_test(test_encode_and_decode_base64); mu_run_test(test_bounds_check_on_decode); mu_run_test(base64_decode_block_decodes_4_chars); mu_run_test(base64_decode_fails_with_invalid_lengths); mu_run_test(base64_decode_decodes_strings_without_padding); mu_run_test(base64_decode_decodes_strings_with_padding); mu_run_test(base64_encode_block_encodes_3_bytes); mu_run_test(base64_encode_fails_with_invalid_lengths); mu_run_test(base64_encode_encodes_without_padding); mu_run_test(base64_encode_encodes_with_padding); mu_run_test(writes_and_reads_log); mu_run_test(log_reader_aggregates_into_single_histogram); mu_run_test(log_reader_fails_with_incorrect_version); mu_run_test(test_string_encode_decode); mu_run_test(decode_v2_log); mu_run_test(decode_v1_log); mu_run_test(decode_v0_log); free(raw_histogram); free(cor_histogram); mu_ok; } static int hdr_histogram_log_run_tests() { struct mu_result result = all_tests(); if (result.message != 0) { printf("hdr_histogram_log_test.%s(): %s\n", result.test, result.message); } else { printf("ALL TESTS PASSED\n"); } printf("Tests run: %d\n", tests_run); return result.message == NULL ? 0 : -1; } int main() { return hdr_histogram_log_run_tests(); } diskscan-0.21/hdrhistogram/test/hdr_histogram_perf.c000066400000000000000000000031771456470715000227400ustar00rootroot00000000000000/** * hdr_histogram_perf.c * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #include #include #include #include #include "hdr_time.h" static struct timespec diff(struct timespec start, struct timespec end) { struct timespec temp; if ((end.tv_nsec-start.tv_nsec) < 0) { temp.tv_sec = end.tv_sec - start.tv_sec - 1; temp.tv_nsec = 1000000000 + end.tv_nsec-start.tv_nsec; } else { temp.tv_sec = end.tv_sec - start.tv_sec; temp.tv_nsec = end.tv_nsec - start.tv_nsec; } return temp; } int main() { struct hdr_histogram* histogram; int64_t max_value = INT64_C(24) * 60 * 60 * 1000000; int64_t min_value = 1; int result = -1; result = hdr_init(min_value, max_value, 4, &histogram); if (result != 0) { fprintf(stderr, "Failed to allocate histogram: %d\n", result); return -1; } struct timespec t0; struct timespec t1; setlocale(LC_NUMERIC, ""); int64_t iterations = 400000000; int i; for (i = 0; i < 100; i++) { int64_t j; hdr_gettime(&t0); for (j = 1; j < iterations; j++) { hdr_record_value(histogram, j); } hdr_gettime(&t1); struct timespec taken = diff(t0, t1); double time_taken = taken.tv_sec + taken.tv_nsec / 1000000000.0; double ops_sec = (iterations - 1) / time_taken; printf("%s - %d, ops/sec: %'.2f\n", "Iteration", i + 1, ops_sec); } return 0; } diskscan-0.21/hdrhistogram/test/hdr_histogram_test.c000066400000000000000000000335771456470715000227720ustar00rootroot00000000000000/** * hdr_histogram_test.c * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #include #include #include #include #include #include #include "minunit.h" static bool compare_values(double a, double b, double variation) { return compare_double(a, b, b * variation); } static bool compare_percentile(int64_t a, double b, double variation) { return compare_values((double) a, b, variation); // return fabs(a - b) <= b * variation; } int tests_run = 0; static struct hdr_histogram* raw_histogram = NULL; static struct hdr_histogram* cor_histogram = NULL; static struct hdr_histogram* scaled_raw_histogram = NULL; static struct hdr_histogram* scaled_cor_histogram = NULL; static void load_histograms() { const int64_t highest_trackable_value = INT64_C(3600) * 1000 * 1000; const int32_t significant_figures = 3; const int64_t interval = INT64_C(10000); const int64_t scale = 512; const int64_t scaled_interval = interval * scale; int i; if (raw_histogram) { free(raw_histogram); } hdr_init(1, highest_trackable_value, significant_figures, &raw_histogram); if (cor_histogram) { free(cor_histogram); } hdr_init(1, highest_trackable_value, significant_figures, &cor_histogram); if (scaled_raw_histogram) { free(scaled_raw_histogram); } hdr_init(1000, highest_trackable_value * 512, significant_figures, &scaled_raw_histogram); if (scaled_cor_histogram) { free(scaled_cor_histogram); } hdr_init(1000, highest_trackable_value * 512, significant_figures, &scaled_cor_histogram); for (i = 0; i < 10000; i++) { hdr_record_value(raw_histogram, 1000); hdr_record_corrected_value(cor_histogram, 1000, interval); hdr_record_value(scaled_raw_histogram, 1000 * scale); hdr_record_corrected_value(scaled_cor_histogram, 1000 * scale, scaled_interval); } hdr_record_value(raw_histogram, 100000000); hdr_record_corrected_value(cor_histogram, 100000000, 10000L); hdr_record_value(scaled_raw_histogram, 100000000 * scale); hdr_record_corrected_value(scaled_cor_histogram, 100000000 * scale, scaled_interval); } static char* test_create() { struct hdr_histogram* h = NULL; int r = hdr_init(1, INT64_C(3600000000), 3, &h); mu_assert("Failed to allocate hdr_histogram", r == 0); mu_assert("Failed to allocate hdr_histogram", h != NULL); mu_assert("Incorrect array length", compare_int64(h->counts_len, 23552)); free(h); return 0; } static char* test_create_with_large_values() { struct hdr_histogram* h = NULL; int r = hdr_init(20000000, 100000000, 5, &h); mu_assert("Didn't create", r == 0); hdr_record_value(h, 100000000); hdr_record_value(h, 20000000); hdr_record_value(h, 30000000); mu_assert( "50.0% Percentile", hdr_values_are_equivalent(h, 20000000, hdr_value_at_percentile(h, 50.0))); mu_assert( "83.33% Percentile", hdr_values_are_equivalent(h, 30000000, hdr_value_at_percentile(h, 83.33))); mu_assert( "83.34% Percentile", hdr_values_are_equivalent(h, 100000000, hdr_value_at_percentile(h, 83.34))); mu_assert( "99.0% Percentile", hdr_values_are_equivalent(h, 100000000, hdr_value_at_percentile(h, 99.0))); return 0; } static char* test_invalid_significant_figures() { struct hdr_histogram* h = NULL; int r = hdr_alloc(36000000, -1, &h); mu_assert("Result was not EINVAL", r == EINVAL); mu_assert("Histogram was not null", h == 0); r = hdr_alloc(36000000, 6, &h); mu_assert("Result was not EINVAL", r == EINVAL); mu_assert("Histogram was not null", h == 0); return 0; } static char* test_invalid_init() { struct hdr_histogram* h = NULL; mu_assert("Should not allow 0 as lowest trackable value", EINVAL == hdr_init(0, 64*1024, 2, &h)); mu_assert("Should have lowest < 2 * highest", EINVAL == hdr_init(80, 110, 5, &h)); return 0; } static char* test_total_count() { load_histograms(); mu_assert("Total raw count != 10001", raw_histogram->total_count == 10001); mu_assert("Total corrected count != 20000", cor_histogram->total_count == 20000); return 0; } static char* test_get_max_value() { load_histograms(); int64_t actual_raw_max = hdr_max(raw_histogram); mu_assert("hdr_max(raw_histogram) != 100000000L", hdr_values_are_equivalent(raw_histogram, actual_raw_max, 100000000)); int64_t actual_cor_max = hdr_max(cor_histogram); mu_assert("hdr_max(cor_histogram) != 100000000L", hdr_values_are_equivalent(cor_histogram, actual_cor_max, 100000000)); return 0; } static char* test_get_min_value() { load_histograms(); mu_assert("hdr_min(raw_histogram) != 1000", hdr_min(raw_histogram) == 1000); mu_assert("hdr_min(cor_histogram) != 1000", hdr_min(cor_histogram) == 1000); return 0; } static char* test_percentiles() { load_histograms(); mu_assert("Value at 30% not 1000.0", compare_percentile(hdr_value_at_percentile(raw_histogram, 30.0), 1000.0, 0.001)); mu_assert("Value at 99% not 1000.0", compare_percentile(hdr_value_at_percentile(raw_histogram, 99.0), 1000.0, 0.001)); mu_assert("Value at 99.99% not 1000.0", compare_percentile(hdr_value_at_percentile(raw_histogram, 99.99), 1000.0, 0.001)); mu_assert("Value at 99.999% not 100000000.0", compare_percentile(hdr_value_at_percentile(raw_histogram, 99.999), 100000000.0, 0.001)); mu_assert("Value at 100% not 100000000.0", compare_percentile(hdr_value_at_percentile(raw_histogram, 100.0), 100000000.0, 0.001)); mu_assert("Value at 30% not 1000.0", compare_percentile(hdr_value_at_percentile(cor_histogram, 30.0), 1000.0, 0.001)); mu_assert("Value at 50% not 1000.0", compare_percentile(hdr_value_at_percentile(cor_histogram, 50.0), 1000.0, 0.001)); mu_assert("Value at 75% not 50000000.0", compare_percentile(hdr_value_at_percentile(cor_histogram, 75.0), 50000000.0, 0.001)); mu_assert("Value at 90% not 80000000.0", compare_percentile(hdr_value_at_percentile(cor_histogram, 90.0), 80000000.0, 0.001)); mu_assert("Value at 99% not 98000000.0", compare_percentile(hdr_value_at_percentile(cor_histogram, 99.0), 98000000.0, 0.001)); mu_assert("Value at 99.999% not 100000000.0", compare_percentile(hdr_value_at_percentile(cor_histogram, 99.999), 100000000.0, 0.001)); mu_assert("Value at 100% not 100000000.0", compare_percentile(hdr_value_at_percentile(cor_histogram, 100.0), 100000000.0, 0.001)); return 0; } static char* test_recorded_values() { load_histograms(); struct hdr_iter iter; int index; // Raw Histogram hdr_iter_recorded_init(&iter, raw_histogram); index = 0; while (hdr_iter_next(&iter)) { int64_t count_added_in_this_bucket = iter.specifics.recorded.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Value at 0 is not 10000", count_added_in_this_bucket == 10000); } else { mu_assert("Value at 1 is not 1", count_added_in_this_bucket == 1); } index++; } mu_assert("Should have encountered 2 values", index == 2); // Corrected Histogram hdr_iter_recorded_init(&iter, cor_histogram); index = 0; int64_t total_added_count = 0; while (hdr_iter_next(&iter)) { int64_t count_added_in_this_bucket = iter.specifics.recorded.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Count at 0 is not 10000", count_added_in_this_bucket == 10000); } mu_assert("Count should not be 0", iter.count != 0); mu_assert("Count at value iterated to should be count added in this step", iter.count == count_added_in_this_bucket); total_added_count += count_added_in_this_bucket; index++; } mu_assert("Total counts should be 20000", total_added_count == 20000); return 0; } static char* test_linear_values() { load_histograms(); struct hdr_iter iter; int index; // Raw Histogram hdr_iter_linear_init(&iter, raw_histogram, 100000); index = 0; while (hdr_iter_next(&iter)) { int64_t count_added_in_this_bucket = iter.specifics.linear.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Count at 0 is not 10000", count_added_in_this_bucket == 10000); } else if (index == 999) { mu_assert("Count at 999 is not 1", count_added_in_this_bucket == 1); } else { mu_assert("Count should be 0", count_added_in_this_bucket == 0); } index++; } mu_assert("Should of met 1000 values", compare_int64(index, 1000)); // Corrected Histogram hdr_iter_linear_init(&iter, cor_histogram, 10000); index = 0; int64_t total_added_count = 0; while (hdr_iter_next(&iter)) { int64_t count_added_in_this_bucket = iter.specifics.linear.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Count at 0 is not 10001", count_added_in_this_bucket == 10001); } total_added_count += count_added_in_this_bucket; index++; } mu_assert("Should of met 10001 values", index == 10000); mu_assert("Should of met 20000 counts", total_added_count == 20000); return 0; } static char* test_logarithmic_values() { load_histograms(); struct hdr_iter iter; int index; hdr_iter_log_init(&iter, raw_histogram, 10000, 2.0); index = 0; while(hdr_iter_next(&iter)) { long count_added_in_this_bucket = iter.specifics.log.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Raw Logarithmic 10 msec bucket # 0 added a count of 10000", 10000 == count_added_in_this_bucket); } else if (index == 14) { mu_assert("Raw Logarithmic 10 msec bucket # 14 added a count of 1", 1 == count_added_in_this_bucket); } else { mu_assert("Raw Logarithmic 10 msec bucket added a count of 0", 0 == count_added_in_this_bucket); } index++; } mu_assert("Should of seen 14 values", index - 1 == 14); hdr_iter_log_init(&iter, cor_histogram, 10000, 2.0); index = 0; int total_added_count = 0; while (hdr_iter_next(&iter)) { long count_added_in_this_bucket = iter.specifics.log.count_added_in_this_iteration_step; if (index == 0) { mu_assert("Corrected Logarithmic 10 msec bucket # 0 added a count of 10001", 10001 == count_added_in_this_bucket); } total_added_count += count_added_in_this_bucket; index++; } mu_assert("Should of seen 14 values", index - 1 == 14); mu_assert("Should of seen count of 20000", total_added_count == 20000); return 0; } static char* test_reset() { load_histograms(); // before mu_assert("Value at 99% == 0.0", hdr_value_at_percentile(raw_histogram, 99.0) != 0); mu_assert("Value at 99% == 0.0", hdr_value_at_percentile(cor_histogram, 99.0) != 0); hdr_reset(raw_histogram); hdr_reset(cor_histogram); //after mu_assert("Total raw count != 0", raw_histogram->total_count == 0); mu_assert("Total corrected count != 0", cor_histogram->total_count == 0); mu_assert("Value at 99% not 0.0", hdr_value_at_percentile(raw_histogram, 99.0) == 0); mu_assert("Value at 99% not 0.0", hdr_value_at_percentile(cor_histogram, 99.0) == 0); return 0; } static char* test_scaling_equivalence() { load_histograms(); mu_assert( "Averages should be equivalent", compare_values( hdr_mean(cor_histogram) * 512, hdr_mean(scaled_cor_histogram), 0.000001)); mu_assert( "Total count should be equivalent", compare_int64( cor_histogram->total_count, scaled_cor_histogram->total_count)); int64_t expected_99th = hdr_value_at_percentile(cor_histogram, 99.0) * 512; int64_t scaled_99th = hdr_value_at_percentile(scaled_cor_histogram, 99.0); mu_assert( "99%'iles should be equivalent", compare_int64( hdr_lowest_equivalent_value(cor_histogram, expected_99th), hdr_lowest_equivalent_value(scaled_cor_histogram, scaled_99th))); return 0; } static char* test_out_of_range_values() { struct hdr_histogram *h; hdr_init(1, 1000, 4, &h); mu_assert("Should successfully record value", hdr_record_value(h, 32767)); mu_assert("Should not record value", !hdr_record_value(h, 32768)); return 0; } static struct mu_result all_tests() { mu_run_test(test_create); mu_run_test(test_invalid_init); mu_run_test(test_create_with_large_values); mu_run_test(test_invalid_significant_figures); mu_run_test(test_total_count); mu_run_test(test_get_min_value); mu_run_test(test_get_max_value); mu_run_test(test_percentiles); mu_run_test(test_recorded_values); mu_run_test(test_linear_values); mu_run_test(test_logarithmic_values); mu_run_test(test_reset); mu_run_test(test_scaling_equivalence); mu_run_test(test_out_of_range_values); mu_ok; } static int hdr_histogram_run_tests() { struct mu_result result = all_tests(); if (result.message != 0) { printf("hdr_histogram_test.%s(): %s\n", result.test, result.message); } else { printf("ALL TESTS PASSED\n"); } printf("Tests run: %d\n", tests_run); return result.message == NULL ? 0 : -1; } int main() { return hdr_histogram_run_tests(); } diskscan-0.21/hdrhistogram/test/hiccup.140623.1028.10646.hlog000066400000000000000000000031371456470715000226560ustar00rootroot00000000000000#[Logged with jHiccup version 2.0.3-SNAPSHOT] #[Histogram log format version 1.01] #[StartTime: 1403476110.183 (seconds since epoch), Mon Jun 23 10:28:30 NZST 2014] "StartTimestamp","EndTimestamp","Interval_Max","Interval_Compressed_Histogram" 0.042,5.004,0.115,HISTiQAAAEV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQt4QmrkKQvNugkq8g9KKUJoHSjMzoAJGhlEwCkbBKBgFo2AUDDkAANEpBrU= 5.046,5.000,1.294,HISTiQAAAEh42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQm5QBhuEYraF0LyuEJoxFypvA6UFoTQzwygYBZQDxtEgGAWjYBSMgoEBAItJBaw= 10.046,5.000,3.113,HISTiQAAAEZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQlFQBiMqzX8RQjNJQMVDobQwlGZCo0fB8ASMo0EwGs+jYDS+R8HwBAC+mAXU 15.046,5.005,0.131,HISTiQAAAEd42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQhlQBiOU5oBQAuxQ4a9QcW8oLQKlmRlQASPDKBgFo2AUjIJRMAqGDAAAoysF8A== 20.051,4.995,0.147,HISTiQAAAEp42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQglQBlSegRlCCXhAaMbtUHE3KM0PpVmhNCMDKkDnj4JRMApGwSgYBaNgEAIAJgsF4A== 25.046,5.000,0.115,HISTiQAAAEZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQilQBiOUZoNQAnJQ4bNQ8UgoLQylWaA01NxRMApGwSgYBaNgFAwlAABjqwXo 30.046,5.000,0.131,HISTiQAAAEJ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQqkMqIARQgl4Q7n7oOJeUJoPSjNh1zcKRsEoGAWjYBSMgqEAAHWdBeo= 35.046,5.000,0.115,HISTiQAAAEV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQqlQBlSegRlCCWhDaMYzUPFgKC0CpRnR6FEwCkbBKBgFo2AUDCEAAHRlBeo= 40.046,5.000,0.131,HISTiQAAAER42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQikMqIAZQgloQWjGy1DxACjNi6oOTjMyjIJRMApGwSgYBaNgyAAAZDsF6A== 45.046,5.000,0.131,HISTiQAAAEl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQvFQBlSegQNC8W2BCp+Bis+H0hpQmgtKM0NpRoZRMApGwSgYBaNgFAwZAADuSAbd 50.046,5.000,0.246,HISTiQAAAEt42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMQvFQBlSegQ1CMd6G0PxuUPFbUNoJSotDaUY0mlRArr5RMApGwSgYBaNgFFAAAOooBt0= diskscan-0.21/hdrhistogram/test/jHiccup-2.0.1.logV0.hlog000066400000000000000000000335271456470715000226120ustar00rootroot00000000000000#[Logged with jHiccup version 2.0.1] #[Histogram log format version 1.01] #[StartTime: 1438869961.225 (seconds since epoch), Thu Aug 06 07:06:01 PDT 2015] "StartTimestamp","EndTimestamp","Interval_Max","Interval_Compressed_Histogram" 0.116,1.005,3.031,HISTiQAAAG542pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI+gDFYozQmlOaA0M5Rmg9LsUJoFjc+GZg4rmjkwdUxofG4obQeldaG0LJTmR1PvCKXVIRQjzL2BUFoYTT0jwyjABkbDZTSeR8FofI+CEQ4AUBEGxA== 1.121,1.000,0.442,HISTiQAAAGR42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA+hDEY0mhVKc0BpdijNAqW50NSx4dDPhqafDYf5OlDaGEpLQmleNPs8oLQy1LoYVD5cPcydUH+PglEwCkbBKBgFowAZAABAZwbC 2.121,0.999,0.459,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPcYsANmNJoNB82Jpo4Fjc8NpVlhFkJpLijNDqV1obQGlFZEMx+mLghKK0AoxigoXxVKi0NpRjT/MDKMglEwCkbBKBgFowAOAAw5Brw= 3.120,1.002,0.442,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPehDEYozYxGs0BpVjQ+F5o+dhz6OWAWoZkDU88GpXWhtCqU1kDTD9MXAqXVodb7QvlmUJoXzZ0w942CUTAKRsEoGAWjAAkAABrTBr4= 4.122,1.000,0.475,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPcYsAOoegY2ND6MZoHSXFCaHU09jM+Kpp4NB60DpfWhtByU5kYzLxBK60EoRncoXwNKS0BpZhz+YmQYBaNgFIyCUTAKRgEDAArJBrw= 5.122,1.000,0.442,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTHcZUAEjTAJKs0BpNjRxGJ8dSnOgibPioFlw8JWhtBqUloXSPFCaC0qHQWltqHPDoXwtKC2MZj4jwygYBaNgFIyCUTAKMAAA+GAGug== 6.122,1.001,0.459,HISTiQAAAGd42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTHcZsANGmAIozQKlWaE0M5RmQxOHqeNAU8eOpp4Lja8JpbWhtC6U5kQzPwRKa0CdaQPlm0JpYTRzGdHoUTAKRsEoGAWjYBQAAQD4sAa6 7.123,0.997,0.541,HISTiQAAAGt42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI+gDBYozYhGs6HJw/isaOpY0dTBaA4ozQmlmdHkeaG0HZR2gdKKUJodzV5VKO0Kpe9D6UooLQaludDcRywgVf0oGAWjYBSMglEwJAEAhtAHww== 8.120,1.001,0.459,HISTiQAAAGJ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTHcZsANGKM0MUwilWXHQMHXsaHwWNBomzonGl4PSulBaEUoLoZkrD6XdofQbKL0CSsuiqUf3zygYBaNgFIyCUTAKgAAAJX4HuQ== 9.121,0.999,0.442,HISTiQAAAGJ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI+hDBY0mhWNhomzodEweSYc5jDjMIcTjTaC0i5QWhVK86Cpk4DSDlD6NZSuh9KSUJoDSjMyjIJRMApGwSgYBaMAAwAAlsoHxQ== 10.120,1.001,0.459,HISTiQAAAGB42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA8ZUAETGs0KpZmhNDsazYKmDpd+GM2NQ582lFZDoznR7FeE0iEQilEKyi+E0vxo+mCAkWEUjIJRMApGwSgYBXAAADJXBsI= 11.121,1.000,0.442,HISTiQAAAGh42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPegDEYozQyTgNLsaOLMaOpZ0NSzQmkuHPIw8zjRzFOB0jpQWhFK80NpHigtDaVdoPR3KD0dSkug2Q9z5ygYBaNgFIyCUTAKkAAAOxAHuw== 12.121,2.238,1568.670,HISTiQAAAOl42u2aMQ7CMAxFnZaqILEhISQYOAIjJ2Bk40YM7FyAMzBxPCRwhkYqlUpTTPL+8uXEdv6312zO14uIFPLCcStSHnaP2zuU6VyacAF7VMraRyZBXAfnZcBVy71/Z6m8Vl55gUG+17tXviuflBct+sAwcIyAPQP2DNgz/vGNX3wb1OUy3QPzxreF/r+qz+1ddDOvGHWu572L1DdVXcyTPVvS5TrqrMTozEMn8xtHpzUujOtDJ3NMSV/Rk8sv6/+tH77pl6JO/18m/KfTxtbzUvPDfPAdM8//s5t1xGPloWeY+loA+IAnHpcMHQ== 14.359,0.761,0.459,HISTiQAAAGp42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTFZQBhuUZsHBZ4bSHFCaFY2Gms/AjqafFYe5MPP4oLQWlLaB0mJQWhhKc0FpfihtBKX7oHQilBZAswfmLkaGUTAKRsEoGAWjYBTAAQCDmgZz 15.120,1.000,0.442,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPcZUAEjGs2GRnOi8VmgNDManxtNnBlNH9Q9DOxQWhBK60FpeTRxDijNC6XDofRpKH0JSguj2c/IMApGwSgYBaNgFIwCDAAAR8IHvQ== 16.120,1.002,0.475,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPehDEY0mhmNZoHS7Gg0CxoNU8+GQx4mzoTGl4PSulBaA0qLQGluKM0Ppb2g9EYofRdKi6Kph9nLgOa/UTAKRsEoGAWjYEQDAEgCB70= 17.122,1.001,0.475,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTE8ZUAEjlGaFKUCj2aA0N5RmgdLsaPIsOPgcaHyYuTZQ2hBKq0BpUSjNCaWFobQvlD4IpVdCaXEozYXmH3R6FIyCUTAKRsEoGNEAAK+GB8k= 18.123,1.001,0.426,HISTiQAAAGJ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI8ZsAOoegYWHDQblGZFo7mhNCeU5sKhnx2NlofSZlBaEUqLQmkOKC0EpcOg9H4ovQVKy6G5ZxSMglEwCkbBKBgFWAAAjYoHxQ== 19.124,0.996,0.426,HISTiQAAAGN42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTE9gDCjNBqVZ0GhmKM2KQx2MzwmleaA0OxrNhGYeTL0hlHaC0gY4zOOH0ilQeh2U7oHSMlCai2EUjIJRMApGwSgYBTgBAKssB8c= 20.120,1.003,0.459,HISTiQAAAGh42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI8ZUAFUHQMjlGZBo1mhNDsOPgeaek4ozQyluaA0N5p+ESitC6W10NTB3CUMpUOh9EYofQFKy6PZw4zmn1EwCkbBKBgFo2AUAAEAiFIHxQ== 21.123,0.997,0.442,HISTiQAAAGR42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTHdhDCjNiMaH0cxQmgNNnAuNzwalWdHMY0ETR1cnAaUdoLQylBZGswfG94bSZ6H0DigtCqV50OwfBaNgFIyCUTAKRgESAAArzge5 22.120,1.000,0.475,HISTiQAAAGh42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTO+gDBYozQylWaE0B5o8D5RmQ6PZoTQnmn6YODcanw3NvEQo7QGlZaA0L5r9YlDaHEp3Q+kVaPLo+mCAkWEUjIJRMApGwSgYBQwAU9cH2w== 23.120,1.002,0.442,HISTiQAAAGd42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA8ZUAFUHQMLGs0OpdmgNCuaOIzPCaWZ0fSzotFsaPaJQWkdKC0BpXnQaFEoHQulL0DpTVBaBkoLobljFIyCUTAKRsEoGAVIAABnpgfB 24.122,1.001,0.475,HISTiQAAAGh42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTM9gDDSahQEVsKGJc0JpdhzizFCaFUrzQGkONH1cUNoISjtDaTUoLYCmng9Ku0Dp+VD6KJQWgtL8DNgBI8MoGAWjYBSMglEwChgAxMAHyw== 25.123,0.997,0.459,HISTiQAAAGt42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA8ZsANmKM0CpbmgNCeUZofSrGh8DijNhmYejM+NZh7MfBkobQyllaE0H5q9wlDaD0qfh9KroLQ4mvlQfzMwMoyCUTAKRsEoGAWjAA4AcjYHwQ== 26.120,1.003,0.426,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTE8ZUAEjlGZFo5mhNBuU5oTSLGg0O5o+FjQ+OxoNk1eF0gZQ2gRK86GpF4LSPlB6I5Q+BaVFoTQvwygYBaNgFIyCUTAKcAIArGYHyQ== 27.123,0.997,0.475,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPcZUAEzGs0KpVmgNBuaOBcanxNNHQuaPIxmh9KMUFoMSutBaWUoLYLmHgkoHQ2l70DpJWjqOdHMR6dHwSgYBaNgFIyCEQ0ATtIHvQ== 28.120,1.004,0.623,HISTiQAAAG142pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI8ZUAEzlGaDKYDSrGjyXFCaHU2eA43PiKaPBc1cmD2SUNoUSqtDaX40+0SgdCCU3g+lT0JpYSjNg2Y/Aw4+uYBa5oyCUTAKRsEoGAUDAgCJQgfF 29.124,0.997,0.459,HISTiQAAAGd42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTM+gDGYozYJGc+CQZ4XS3FCaHUpzouljQ1PPhibPB6UNobQmlDZBM48LSotBaTcovQFKb4fSPGg0DDAyjIJRMApGwSgYBaMADgDKMAfL 30.121,0.999,0.475,HISTiQAAAG542pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI8YUAELlGZG48NoqDkMvFCaE0qz46A5oDQblOZCMx+mTgpKG0FpTSgtAKUFobQYlHaC0jCPHIfSslCaD0ozormbkWEUjIJRMApGwSgYBQwAgpgHww== 31.120,1.000,0.475,HISTiQAAAGp42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA8YUAEzlGaEKUATZ4PS7FCaBU0dB5RmRaNZ0PSxoYnLQmlrKK0GpfnQzJeG0o5Qei+UvgClJaE0J5q7GdD8NQpGwSgYBaNgFIxoAABYbAe/ 32.120,1.004,0.459,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA8ZUAEjlGaB0qxoNNQcBnY0deji6Hx0c2D6mKG0JJRWh9JKUFoQSnNCaSEonQil10HpJ1BaHIc7GBlGwSgYBaNgFIyCUQAHAGMmB8E= 33.124,0.996,0.492,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA+gDEY0mgVKM0NpNhw0K5Rmh9KcUJoDTR07DhomrwSlbaC0Mpo5MPVCUNoPSh+H0mugtCiU5oF5kAE7YGQYBaNgFIyCUTAKRjAAAGPcB78= 34.120,1.003,0.442,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTG+gDGYozYJGw8Q5oDQnlGZDk0cXZ0cT50QzlxVKc0NpHSjtAqWNobQgmj5xKG0NpTdD6RVQWhhK88E8yDAKRsEoGAWjYBSMAgwAACgzB9c= 35.123,0.998,0.475,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPdhDCjNiEazQGkOKM2KRjOj0Rxo5rGjqUc3ByYvC6X1obQulBaG0mxQWhRKu0LpLVD6MpQWgdJcaO5iQPPXKBgFo2AUjIJRMKIBAEwqB70= 36.121,1.003,0.475,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTE8ZUAELGg3Vx8CBJs4NpdmhNCuUZkZTx4qmDibOiWauHJQ2htLqUFoYSnNBaSEoHQylD0DpVWjmwNzHiIMeBaNgFIyCUTAKRjQAAK6eB8k= 37.124,0.998,0.442,HISTiQAAAGp42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI8YUAEHlGaB0sxQmg2NZofSrGg0Gxofpo4LzVwONFoBShtCaTUozQulOaG0EJQOgNI7oPRuKC0CpflgHmQYBaNgFIyCUTAKRgEGAACDQAfD 38.122,1.001,0.524,HISTiQAAAGt42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI+hDEYozQKl2dDE2dBomDpWKM2MQ54dSnOgyTOh8SWhtD6UVoPSvGjmSEDpFCj9GUo3Q2lhKM2D5i6YP3ABQvKjYBSMglEwCkbBsAIAi7IHxQ== 39.123,1.001,0.475,HISTiQAAAG542pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTO8YUAELlGaD0pxQmhtK80JpDjR1glCaC0ozo5nHgWYeE5q4LpQOhdLKUFoYSvNAaQko7QylJ0LpZWjqYe5kRPMfOn8UjIJRMApGwSgYkQAAVCcH2w== 40.124,1.000,0.442,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTC+hDEY0mhWN5ofSXFCaDUpzQGl2KM2MQ5wDh7kwcxSgtBmUNobSslBaCEpLQukgKL0FSvdCaREozQmlWRhGwSgYBaNgFIyCUYABAPuGB9E= 41.124,0.996,0.475,HISTiQAAAGd42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI+hDGaYAJRmgdJsUJoDjWZB08eFJs+OJg8TZ8WhThNKG0FpPSjNj0ZLQGlvKL0ISm+D0mJQmhPNP4xo9CgYBaNgFIyCUTCiAQCYogfF 42.120,1.004,0.475,HISTiQAAAGp42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTC9hDCjNCqXZ0PgsOMRhfHYozYEmzwyledDkWdDUKUBpWyhtCqXFoDQXlBaC0m5QeiGU3gmlRdHUwfwFA4wMo2AUjIJRMApGwShgAADzjgfR 43.124,0.996,0.442,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPcYUAFUHQMzlGZHE2dCE4fRLDhoDjQ+Nw5xGSitDaVVobQwlGaF0uJQOgVKL4bSu6C0CpQWgNKMDKNgFIyCUTAKRsEowAAAPDAHuw== 44.120,1.004,0.459,HISTiQAAAGN42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA8YUAEjDj4rTAManwVKs6PxOdDUM6OpY0WjRaC0NZRWhtICUJobTV0wlL4IpTdAaSUozYVmL7q/RsEoGAWjYBSMghENAFMcB78= 45.124,0.999,0.459,HISTiQAAAGN42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTDcZsANGmAI0mhlNnhVKs0FpFjT1rDhoFjS+GJTWgdKKUJofzXwYPwJK74fSl6G0KpTmQbOHkWEUjIJRMApGwSgYBXAAAN73B7E= 46.123,1.001,0.442,HISTiQAAAGh42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMzGxQBlSegQNKs0JpdijNB6W5oDQbGs2Bph5Gs8AsQqNZUNUxhkH5hVBaFs0cJjT75KG0C5S2Q3MHzHxGhlEwCkbBKBgFo2AUYAAAlrEGDQ== 47.124,1.409,1233.125,HISTiQAAAMt42u2asQ3CMBREzzZG0DEABSMwBSU1FdNQ0LMAYzAeEpiCL1kCR8YmeddcfvL/9925zfp0OUvyemC/kcJue7s+S8VjepgldnqHN6xMX8jsCWbezsXEh8SrTJ+tQV2QN/cMuGfAPZMHfvGN33/Q5/DNufhudo5r7A/d6Cav4fOucE+r7+giT3QP19VrjU7yQ2c9nb2w71QXOslxzPr8lxwK5369d2r78M2+En79txNNneOp9eGbvjH7WSZeGP70fa2+uQAA1XAH+BcJvg== 48.533,0.591,0.311,HISTiQAAAFR42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMjNegDKg8AxeUZkGjWdFoTijNjqaODY2GqWdEU8eMqo5RHMpPRnMHTN8oGAWjYBSMglEwCqgIAEz/Bas= 49.124,1.000,0.442,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTH+hDHYozQGlWaA0M5RmhdJsaDQ7Gp8Djc+Iwzw09YzcUH41lJZBs5cXzXxlKO0DpdOgNDeau6D+HgWjYBSMglEwCkYBMgAA774G+g== 50.124,1.000,0.442,HISTiQAAAGR42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTLcZUAETGp8ZSjNCaRYozYomz46mH5c+dhzmy0JpbSitBqX5oTQHlOaD0n5QeibUGph75ND0oftnFIyCUTAKRsEoGAVAAADL1Aa2 51.124,1.000,0.442,HISTiQAAAGN42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTHcZsANWKM2CxofR7FCaEYc6qH0MbGg0TJwTzRwY3xJKi0FpPijNgcaPhdIbofQjKK0EpbnQ3DcKRsEoGAWjYBSMAiQAACOuB7k= 52.124,1.000,0.475,HISTiQAAAGd42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI8YUAFUHQMrlGZD46PTHFCaB0ozo+lDp5nQ1PFDaVEobYDGh5nLAqUFoXQalJ4DpZ9DaXEozYlmDyMaPQpGwSgYBaNgFIxoAAB6gAfD 53.124,0.999,0.442,HISTiQAAAF542pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTO+gDHY0mhNK8+AQZ0UTZ8GhjhOH+TD9vFDaEUp7QGllKM2BZr4Mmrq5UHohmnkwfcwMo2AUjIJRMApGwSjAAABYjwfb 54.123,1.001,0.442,HISTiQAAAGt42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTJ+gDGYozQuluaE0B5RmgdJcUJodSvOgibOg0cxo6tnRxIWgtCuUjoTS0lCaD0pzoqk3h9IdUHorlBZHczcjwygYBaNgFIyCUTAKMAAAl8cH4w== 55.124,0.999,0.442,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI+gDEYozQylWaA0K5o41BwGNjRxbjQ+Kw5z0M3jhdJqUNocSkui0TB1IlDaD0pvhdLHobQglOZC89coGAWjYBSMglEwCpAAAH2wB8M= 56.123,1.001,0.442,HISTiQAAAGR42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTB9hDCjNCaU5oDQXDj4blObFoY4VBw2TZ4fSQlDaF0qbQGllKM2P5i5JKO0KpSdA6eVo5sHUMzKMglEwCkbBKBgFowADAACIDQfh 57.124,0.999,0.459,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTA8YUAEblGaE0swwhVCaA0qzQGl2KM2Kpg5dPTsazYKmThFKm0JpFSjNi2aOIJQOhdLLofQlKC2Npo4RjR4Fo2AUjIJRMApGARAAAFlsB78= 58.123,1.000,0.442,HISTiQAAAGB42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTHcZsAMmHDQLlGaE0hxQmg1Ks6PxWXHoZ0FTJwWlTaC0OpTmQzMHZl8glF4OpX+jqRdAc+coGAWjYBSMglEwCpAAACNmB7k= 59.123,1.001,0.442,HISTiQAAAF942pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTE9gDCjNgkZzoMmzQml2NHVsaHxmKM2Ipp4Zhz5dKO2KxudDs18QSjtD6alQ+gGUFsOhbxSMglEwCkbBKBgFSAAAnxwHxw== 60.124,0.999,0.492,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTLcZUAEjGs0GpVnQ+MxoNEyeFUqzo5nDiaafDU2dBJRWhdLSUJoDTT8flPaB0rOh9A8orQSlZXD4Cxd/FIyCUTAKRsEoGFEAAAFqB7U= 61.123,0.999,0.442,HISTiQAAAGB42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTDcYUAFUHQMjGh+XODMazQKl2QioY0VTLwqlDaG0MJTmRzNPEEqHQeldUPoLlJaF0lxo9o2CUTAKRsEoGAWjAAkAAMvVB68= 62.122,1.000,18.481,HISTiQAAAIp42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTI8ZsAMmHDQrlOaC0mxQmhlKc6Cpg9EsaOpg4pxQWgpKW0FpSSgthKZOFEo7Q2mYR95CaQEozYPDP4wMo2Akg9H4H43nUTAaz6NgNF5G/Tvq71H/Di5/jto76u9Rewev/YxDPBxGwSgYBUgAAP6WB8U= 63.122,1.001,0.459,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTM8ZUAErTAJKs0Fpdhx8VjQ+TB8LGp8Vhz6YeQlQ2hxKS0BpHijNBaX5obQ7lF4GpbdBaRk0cxnR6FEwCkbBKBgFo2AUAAEA1joHzQ== 64.123,1.000,0.442,HISTiQAAAGR42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPehDEaYAAMqYEGTZ4fSHGjqOdDUw2hWND4zGs0GpWWhtBEaXwBK80FpISgdA6VXQ+mLaPp40OwdBaNgFIyCUTAKRgESAABF0ge9 65.123,0.999,0.442,HISTiQAAAGR42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPcYUAEjlGaB0swE+Gxo4mxo8qxofA40cRgtC6UtoLQ8lOaF0lxQmhtKu0PpxVD6C5SWhNL8aP4ZBaNgFIyCUTAKRgESAAA10Ae7 66.122,1.001,0.459,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTM+hDFYozYxGw8TZoDQHmjg3mjyMZoTSLGjqYXx2NPNUoLQrlNaA0nxQmhNKC0Fpfyi9BErvgdLiaPoY0ehRMApGwSgYBaNgFAABANPaB80= 67.123,0.999,0.442,HISTiQAAAGF42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPdhDDSaHUqzoPFZoTQnlGaD0hw4zGFG04euHsaXg9KaUJoPSvOgqReF0hFQej2UfoBmDrp7RsEoGAWjYBSMglGABABLoge9 68.122,1.001,0.475,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTHcZsANGNBqqn4ENSrNCaWY0cRYCfG4ozQGl2aG0IJTWgdJiaPKcUJoPSsdC6R1Q+g2UlkWzDx0wMYyCUTAKRsEoGAWjgAEAIHYHuQ== 69.123,0.999,0.459,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTLcYiAOMUJoNSjOj8dnQ1LNCaXYozYmmjwVKc0BpAShtC6WFoDQ3mnoYPwFK74LSd6C0LJQWhHkQzf2jYBSMglEwCkbBKAACAO+JB7M= 70.122,1.001,0.442,HISTiQAAAGN42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTDcZsANGKM0CpZnRaFY0PhManw1NnAnNPFY0cUUobQSleaA0N5p7OKG0PZTuhkrbQvnSUFoEzfxRMApGwSgYBaNgFCABAKc4BrI= 71.123,0.999,0.426,HISTiQAAAFh42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTHehDBaYAAGaBQfNjEazofFZcfBhtDqUtofSEmjmwOwXgdKBULofQjGiy8PoUTAKRsEoGAWjYBRgAQDzCAa6 72.122,1.001,0.442,HISTiQAAAF142pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTNcZsANGHHwWKM2MRrPgoJnQaBYc+vigtAaUFoDSgmjqeKB0IpReBHWeDJQPo3lx+GMUjIJRMApGwSgYBUAAAIOkBq4= 73.123,1.001,0.475,HISTiQAAAGB42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTNcYsAOoegZGND4LGp8BTR0zGs2Kph6XuSJQ2hBKC0FpPjRzeKC0D5RuhhpnD+XLoulnweHOUTAKRsEoGAWjYEQDAHGaBqw= 74.124,0.999,0.442,HISTiQAAAGJ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTLcYsANGKM0MU4hGs0BpVjQ+G5o6mH52NHlWNHl5KG0JpYWgNBeaOhg/HErPgtJ/obQMmn4OhlEwCkbBKBgFo2AUYAAA7wEHsw== 75.123,1.000,0.459,HISTiQAAAGh42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTLehDGaYAJRmZEAFTGjq0NXDaBY0GqaOC0rzoIlzQGk1KK0DpQWgNBuUZkfTHwylm6HOlYPypdH0M6K5bxSMglEwCkbBKBgFQAAAzUwGtg== 76.123,1.000,0.475,HISTiQAAAGR42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTDcZUAFUHQMjGp8FBw1Tx4YmzoYmz4zDPJi8GJQ2htLCUFoQzTwRKO0BpeugxuhC+bJQWgjNPgY0+0bBKBgFo2AUjIIRDQCpiAay 77.123,1.001,0.459,HISTiQAAAGZ42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPcZsAOoegZmNBpdnBVKc0FpFjR5DjR9LGg0TFwbSptCaRkoLYBmviCUDobSG6D0BSitAKW50cxnZBgFo2AUjIJRMApGARwAAET6B70= 78.124,0.999,0.475,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTFcZsANGNBqqn4EFSrOh8WHqWNHUw2hmHPIwfZxQWgdK80FpDjSaF0p7Q+lpUGPsoXxRKC2Mw32MDKNgFIyCUTAKRsEoYAAAYlAGqg== 79.123,0.999,0.459,HISTiQAAAGV42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTPdgDCjNAqUZ0WiYPDOUZkMTZ8VhDisOdTB5TiitB6U9obQIlOZC0ycApV2gdC/UmTB3SqPpY0bzxygYBaNgFIyCUTAKgAAABCkGvA== 80.122,1.001,0.459,HISTiQAAAGN42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTNcY8ANGKM2Mxoeax8ACpVlxqGNDE0enYeaIQ2lVKC2Aph9Gc0DpWCg9HWqdDpQvCaVF0cxnZBgFo2AUjIJRMApGARwAAHIqBqw= 81.123,0.999,0.557,HISTiQAAAGl42pNpmdzBwMDAxAAGfgoMDMxuBjsWQLgMTFcZiANQ/QxsUJoRSrNAaWY0PjsaH109K5q5glBaHUrzQ2leNPUcUNobSndDjXeG8sWhtDCafQxo7iAEiFU3CkbBKBgFo2AUDEkAAGNwBqo= diskscan-0.21/hdrhistogram/test/jHiccup-2.0.6.logV1.hlog000066400000000000000000000302671456470715000226160ustar00rootroot00000000000000#[Logged with jHiccup version 2.0.6] #[Histogram log format version 1.1] #[StartTime: 1438867590.285 (seconds since epoch), Thu Aug 06 06:26:30 PDT 2015] "StartTimestamp","Interval_Length","Interval_Max","Interval_Compressed_Histogram" 0.133,1.005,2.802,HISTIgAAAFd42pNpmazIwMAYxgABTBDKT4GBgdnNYMcCBvsPUBkeBkYGZqA8MwMbAzsDC5DFBCTZgJCDQY1BjkGLQZRBlUEPCB8zWDCYMxgDZZkZhgJgHDibAY8JB/A= 1.138,0.998,0.475,HISTIgAAAE542pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDDDACMQsQJKRgYOBlYEZCFmAkB3IB/HkGJQYJBi4gXIyDPGMTAxzGKQZ2EC6AJ7YBtg= 2.136,1.001,0.475,HISTIgAAAEt42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDDDACIfMYMjCwArEzEA9TEBSgkGJQZCBn4GLQYDBh+ESw2cGYSBkYWAEAKZvB9Q= 3.137,1.001,0.492,HISTIgAAAE542pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPUBlGsCwTkGYFYg4GFgZmIIsFDNmBcrIMGgz8DDxAMTGGNIZHDPsZpIFskHlMALndB9o= 4.138,0.999,0.492,HISTIgAAAE142pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPUBkWBjY4BpGsQMwOFGcG6mEBQl8GOwZRBj6gGBtDBMMOhpUMUgxcQDkmBkYAwSAH4w== 5.137,1.003,0.459,HISTIgAAAEx42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPcBmQHBuYZmZgZWABYnYgZmNgBLI5GXQYrBj4wSKiDB4MexgeMwgw8DKwAgCbcgfb 6.140,0.998,0.492,HISTIgAAAE542pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDMiAGaiClYGRgR3MYmdgA5JsQDYLgxKDBgM/kGYBkq4MFxg+MEgyCAFVAs0EALiCB9c= 7.138,1.001,0.475,HISTIgAAAE942pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDDDACMQsDMxAyAaE7ECaFcxnAdLMDMoMagxCDBxAcTGGIIZbDBcZRBm4geYxAQCqKAfZ 8.139,0.997,0.459,HISTIgAAAFB42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDDDACMTMQBXsDCxANguQzcLABoQsQMjKIMegzsADFGNmkGBIYGRmWMIgw8DLwAQAj9EG1Q== 9.136,1.004,0.475,HISTIgAAAEx42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDMiACYyZGRiBEESzACEzkMXCoMmgzCDAwM/AysDH4MXwhOE5gwiDIFA1IwCmuAfX 10.140,0.996,0.459,HISTIgAAAE142pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPUBk2IGYBQiYGZgZWIGQBk0wM7AyMQDYbgy6DOQMHAzeQJcTgzHAFCMWBfGYAm8UH2A== 11.136,1.233,1035.993,HISTIgAAAJx42pNpmazIwMD5jgECmCCUnwIDA7ObwY4FDPYfGFABRAUjGDNCWcxgzMnAChZjYeBn0GbQY2ADsoYCYBy1eRCYyjiA/mGkqnpGiuxiHBI2MxLQy0g12cFiMyNJNP1V0d5MRhTMiCGCC1Nb5cDYjB0y4ZShvUr6msgEhsxQGhUyU1lsIHXjMpEFClmxsLCLks4aHOawMDACAO56ClU= 12.369,0.771,0.459,HISTIgAAAEx42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPSDJMDCxAyMTADMSMQMwGJFmBIiC2NIM8gxADO1BMjMGdYT5DL4M4Ax8DEwCR7Acv 13.140,0.996,0.459,HISTIgAAAEp42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDAjACJRnYmBmYAHTrEAWI5hkAdKSDKoMXEDIxiDI4MlwnJGDQQLIYgIAjsYG0A== 14.136,1.001,0.459,HISTIgAAAE142pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDAjAyMACxMxAVSxAyAqk2YAYJMLAIMmgwSDIwAkUFWXwYzjL8JNBnEGAgREAlsUH1A== 15.137,1.002,0.459,HISTIgAAAEx42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPcBlGBmYGViCEkExAmomBBYp5GYwYdBkkGfgY2BiEGFwZLjJcYBBm4GJgBACcBQfc 16.139,0.998,0.475,HISTIgAAAEt42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDMiAEQiZGViBkAUIWcE62IEsZgYpBm0GHiCbk0GQwYfhAcMjBjEgC6geAKdjB9Q= 17.137,1.003,0.475,HISTIgAAAEl42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDMiACQxZGRgZ2ME0M5BkBrNUGLQZBICizAzcDL4M1xneMEgz8AFlGAGnqwfY 18.140,0.998,0.442,HISTIgAAAE142pNpmazIwMBgxgABTBDKT4GBgdnNYMcCBvsPDAxIcswMjAwsYMjAwAaErEBRFqAYI4MDgzKDKAMfgziDHIM5w0WGkwxiDLwAiiQH1Q== 19.138,1.000,0.459,HISTIgAAAE542pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDAjABITMDIwMXECanYGVgYWBDcxiBpKKDCoMQgzcQBEBBh+GjwynGCQZOBiYAJl6B9c= 20.138,1.002,0.557,HISTIgAAAFF42pNpmazIwMDgwgABTBDKT4GBgdnNYMcCBvsPUBlWBhagLAiyACEzWC0jkMUBxIwMbAyaDJYMfAzsQB4/gxvDM4ZTDNIMPEAZBGAEAP1VB+Y= 21.140,0.998,0.459,HISTIgAAAEt42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDDDACIRAYTBkY2AFqmVjYAFiBiCbmUGQQROIuYGiggwejLwMuxhkgCxGAI58BtQ= 22.138,1.000,0.475,HISTIgAAAE542pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDDDACJRlZGBlYIaqYmdgA0IWoBgjUEyGQZlBCMhnYhBlCGOUYFjLIMnACdIBAJ0WBtg= 23.138,0.998,0.492,HISTIgAAAEx42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDDDADJYFkSxADKLZgJgJyldmUGEQYOBhYGXgYwhlZGTYxyDMwM/ACNTBCACrbwbX 24.136,1.003,0.573,HISTIgAAAE942pNpmazIwMDgxgABTBDKT4GBgdnNYMcCBvsPDDDACITMQBXMDBxAkgUIQWxmMIuFQYFBkYGPgQ0oJsUQwsjMsJ1BkkEAZh7MBAD0rQbn 25.139,1.000,0.459,HISTIgAAAEx42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDDDACCbZGFiBkAOokpGBBchiY2AGQxkGTQZBoAgbAy+DKyM7wykgT4CBEQCPpwbX 26.139,0.997,0.475,HISTIgAAAEx42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPUBlGIGQFyjMDSVYGFjBkgoqyALEigzqDMAMnAy+DGIMfoyTDNAYhBh6QCgCfhQbZ 27.136,1.004,0.442,HISTIgAAAEp42pNpmazIwMBgxgABTBDKT4GBgdnNYMcCBvsPDDDAyMAMxixQdSxANgMDGxAyA6EigyoDJwM3AzsDH4M3w3eGGwyyDDwAhpMH1A== 28.140,0.996,0.459,HISTIgAAAEt42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPUBkWoBwIMgNZ7ECaHcxiYWAEk1wMBgxmDGIM3EC+IIMLw2eGTQz8QFEmAJxuB9k= 29.136,1.000,0.492,HISTIgAAAEp42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDKiAEQhZGNiAmBkIGRlYwXwWBmEGZQZ+MEuQIYWRi2EbgwoDB1AOqAMAqa0G1w== 30.136,1.003,0.459,HISTIgAAAE542pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDDDACIQgwMzAxsAChKxAmhlIMwJZzAxSDEoMvAzsQCjE4MPwnuE+gwQDPwMjAJclB9Y= 31.139,0.998,0.459,HISTIgAAAFF42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPUBkuBmagLBMDCwMbkGRkYAVCFiBmAGJmBj4GRQZdBlmgKjYg6cDwk2E+gwQDDwMzAJzYB9s= 32.137,0.999,0.459,HISTIgAAAEp42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPSDKMYMzCwM7AysAMFGEC0iAWCwM3gwyDBgM/mCfIEMfIzrAeSPMzMAIAj9AG1g== 33.136,1.004,0.459,HISTIgAAAE142pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDDDACJbnAGJWMGRiYAZCJgYWIGRmkGNQZRAAyjIzcDKEMrIy7GGQYRBkYAQAj3YG2g== 34.140,0.999,0.442,HISTIgAAAEl42pNpmazIwMBgxgABTBDKT4GBgdnNYMcCBvsPDDDACITMQMwGh6wMLEDIBBRjZZBiUGLgYeAAsngZ3BleMTxmkGHgBQCIIAfT 35.139,1.001,0.459,HISTIgAAAE142pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPcBkWIGZiYAZCCJuZgY2BFYhZgCQXgwmDNgM/AzuQJ8bgzHCX4TyDCAM3AyMAm0EH2g== 36.140,0.996,0.459,HISTIgAAAEp42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDMiAkYEFjNmAKpmhkBUImRjEGOQZ+BnYGTgYJBhCGD4zXGMQZeBhYAQAlpQH0Q== 37.136,1.004,0.475,HISTIgAAAE542pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPUBlGIGRgYAWqYGZgA5IsQJoFzAPxmRkUGYwZhIAsVgYZBmeG3wwHGCQYOEC6AKnrB9w= 38.140,0.996,0.492,HISTIgAAAE542pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDAjAyMAMhEwM7EDMCoZsQDEOoBgLgzyDIgMPkM/KIMJgxfCI4SODOAMv2DxGALigB9c= 39.136,1.000,0.459,HISTIgAAAEt42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDAjAysAIVMECpFmANBsDB5AG8ZiAWI5BhUEKLCbBEMzIyTCPQYyBl4EJAJEUBtg= 40.136,1.000,0.492,HISTIgAAAE942pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPUBkWIGYGQkYgZgGqY2JgB9LMYMgGhIYMDgyyDBwMrAz8DCEMzxlmMkgDWSDACAC9Gwfg 41.136,1.002,0.492,HISTIgAAAE542pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPcBkWIMkMJFmBkJmBF4hBLBYGTqAcO4Migw+DAAMHUFSMwYjhHMNNII8frJMRAL4nB+I= 42.138,0.998,0.475,HISTIgAAAE542pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDAjAyMAMxKxAyMTAAmSzAVnMQMgC5EszaDFwMXAAefwMngyvGZ4wiDIIgPQAAKfOB9U= 43.136,1.002,0.475,HISTIgAAAE542pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDAxIciwMzAxsQAgimYA8RiDJAeSxMygwKDEIMHAC2YIMvgwvGC4zSDHwA+UZAalrB9o= 44.138,1.002,0.492,HISTIgAAAEx42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDAjACMTMQMgKhCCaBcxiYmADyigyKDFwM7AzcDGIMzgzCjBsBdICQFmgLgCrjQbb 45.140,0.996,0.459,HISTIgAAAEt42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPUBkWBkYwZGFgBaoCYTYgyQ7EbEAxNgZjBiMGfjBfjMGB4QPDLgYhII8JAJv1B9g= 46.136,1.003,0.492,HISTIgAAAFF42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPcBlGIGZhYGVgBtLsDBxAmh3MYwHKsDMYMOgySDBwAfmiQNOOMDxiEGIQBsowMDACALywB+E= 47.139,1.001,0.475,HISTIgAAAE542pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDMiAkYGZgQWImYCYmYEViBmBJBNQTJxBg0GEgZOBjYGPIYjhGsNroIgwUIYRAKbXB9Y= 48.140,1.000,0.442,HISTIgAAAEt42pNpmazIwMBgxgABTBDKT4GBgdnNYMcCBvsPDAjAxMDIwAzG7AysDFxAkpmBBUwyMtgwGDIIM/AycDCIMpgz3GI4CaR5AItmB9k= 49.140,1.000,0.459,HISTIgAAAE142pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDMiAiYERCNkZmIGQlYENyGdmYAGKszCIMcgwcAMhFwM/QzjDK4anQBF+BkYAli4H0w== 50.140,2.452,1895.825,HISTIgAAAKx42pNpmazIwMB1hAECmCCUnwIDA7ObwY4FDPYfGGCAEYiZwWoYgZgZzGcCQwYGVgZhBhEGbgZ2BjYgW4+hjqGcgR/IYgSrohxQx5RRm+lpM+OA6aaXzYwDJDtQNjPiVUmKLC1V08pmRqJoRhqoHhw2E8aMA6aS9jYThkxEqSJe3eAykQkJMqPwSBMbSN2UmMjKwAKHrFRhDS1zOBk4gJATijmw8ge5GgDvng6P 52.592,0.546,0.442,HISTIgAAAEl42pNpmazIwMBgxgABTBDKT4GBgdnNYMcCBvsPUBlmoBwLEDMBWcxgkhEqxgpksTNIMQgxcDGwAfl8DDIM1Qy5DLwMrAB+SwaO 53.138,1.002,0.475,HISTIgAAAE142pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPcBlGBmYgZGRgAWImIMkMFmEDslgYOBnMGEwYJBjYGbgZeBkSGG4xrAXzgGoAq7YH3Q== 54.140,1.000,0.524,HISTIgAAAE942pNpmazIwMDgwAABTBDKT4GBgdnNYMcCBvsPDAjACIQgNWxAzMLACsTMQMwEZDEzKDLIMwgycANZ4gz+DI8Y7jBIM/AA5RghOgHYtgfd 55.140,0.996,0.475,HISTIgAAAEh42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDMiAGaiCBQwZwZgZCNnAumQY1Bh4gDwWBkEGZ4bLjMwMkgxCQBlGAJ0MBtI= 56.136,1.000,0.492,HISTIgAAAE942pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPUBkWoBwjEINIZgZWMIuVgQOIWRnYgLKaDPYMXGBRDgYvhhsMVxhkGASB+hgZGAG66gfd 57.136,1.003,0.492,HISTIgAAAFF42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDDDACIQMDCxAkomBFUizMLAxMANFmIF8NgZFBnUGYQYuoCgfgzfDR4brQB4/2DwmALhmB9s= 58.139,0.997,0.475,HISTIgAAAEt42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPUBlGqDwjAwsQsgFpNgZmKASJyDMoMAgx8AJV8DA4M9xheMsgziAClGMEAKc6B9M= 59.136,1.003,0.492,HISTIgAAAE542pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDAjACITMUMjIwAJUzczACsYsDHIMqgz8DNwM7AyCDN4MVxneM8gz8ABVAXUBALeqB9s= 60.139,0.999,0.459,HISTIgAAAE542pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPUBlmoBwLAyOQBrFAkBmMGYFyrAxcDGYMOgwiDAJANbwMrgznGB4ziDJwMjACAJn0B9c= 61.138,1.001,0.492,HISTIgAAAE942pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDDDACJRlYmBmYGVgY2AB8piBkAuIWYCiLAySDM4MQmAZMQZ/hg8MuxhEGHgg+gC7NQfe 62.139,0.999,0.475,HISTIgAAAEt42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDAgAkmUHklwMrAwsQMwMZINYTEAozaDEIAxkMzPIMKQy8jDMA/J4geKMAJ7UBto= 63.138,1.001,13.959,HISTIgAAAGJ42pNpmazIwMC8igECmCCUnwJQzM1gxwIG+w8MDHA5ZiBmZeBgYASS7AwsYD6IzQakVRjUGEQZuICyYgw2DDcY7gLZwkAVIMDIMNQA46jNA2YW45CwmZEikxhpJwsAR+UIUA== 64.139,0.997,0.492,HISTIgAAAE942pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDMiAhYGNgRUIWRiYGdiBmAUI2cGitgx6DJJAmp2BhyGU4SrDbgYBBg6gCkYGRgC9Qwfe 65.136,1.002,0.459,HISTIgAAAE142pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPcBkWBmYGNgZWMGQB8kFsJgZ2BkYg5mXQYNBnEGbgArL5GNwYXjAcANJ8DIwAnS0H3g== 66.138,0.998,0.459,HISTIgAAAEt42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDAjACIasDOxAkgWoloWBGQiZwGwFBjUGHgYOoBw3gx/DBYbfDMIMQgzMAJalB9I= 67.136,1.002,0.492,HISTIgAAAFF42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDDDAApRlYeBgYAOymYEkKxAyglnsQBjLYMEgwMDNwAkk7RiOMexi4GfgAsozMDACAMCHB+Y= 68.138,1.002,0.459,HISTIgAAAEp42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDDDAzMAKVgGiWYAQRHIAITOYJ89gySDMwAMUFWJwYtjD8JJBioGPgRkAmrYH2w== 69.140,1.212,763.363,HISTIgAAAKR42pNpmazIwMCZwwABTBDKT4GBgdnNYMcCBvsPDMiAEQiZgJgFiFnBqpmg+vgY+IEizGBxFYZshjQGbgZ2II8WgDamjtpMG5sZB8xu2tvMSJE87WRpYzYjSXxqqh4cNjOi0IxYRXHR9FdFfTMZoSQhTJyqgVVJqnnEQSYqq6OFSvJMZEKBzGh8XGLEq6SPieTrZgG2a1igED+LeJXYWYwAsfYJeg== 70.352,0.784,0.475,HISTIgAAAFJ42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPUBkuBm4GTgYWBl4gZmFgY+AAqmUEYhYGdiDNw2DGYAMk+YGQl0GLoZ6hDUizAfUxAgCtOgdN 71.136,1.001,0.492,HISTIgAAAEt42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDAjACMaMDKxAzMzADibZgCQLUESFQQ1I8gBFuBhCGLYzCjMIMYiAVTMBAKvBBtk= 72.137,1.003,0.475,HISTIgAAAEt42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDAjAyMAMxEApBhagSiYgyQjEELYsgzoDLwM7kMfFEMBwlpGLQYaBB6QHAJ0DBtc= 73.140,0.996,0.475,HISTIgAAAE942pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDDDACMTMQJKJgR1IsgLZIB4zAwsQszKIMWgyiANpVgZehgiGMwz3GeQZRIEyTACm5QfS 74.136,1.004,0.459,HISTIgAAAEx42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDAjACJZnZmBlYAFCJiBmBLKZgSQLgyiDJgM3AzsQ8jEkMjxkeAYU4WdgAgCWiAfX 75.140,0.997,0.492,HISTIgAAAEx42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDDDACJZnBkIWMIsNiFmBoiARJgZJBmUGYSCfnYGXoYCRiWEngwiQDdLDCACq1wbX 76.137,1.000,0.442,HISTIgAAAE142pNpmazIwMBgxgABTBDKT4GBgdnNYMcCBvsPDDDACJZnYmBmYANiJiCfmYEFCFmBLE4GeQYFBn4gzcIgxuDNcIzhB4M0gwgAho8H0g== 77.137,1.003,0.459,HISTIgAAAE942pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPDMiAkYGZgRWoioWBE8hiZmADirABeawMUgxaDHwMHECeAIMfw2WGrwwiDFwMzACYHQfY 78.140,1.000,0.459,HISTIgAAAFB42pNpmazIwMBgwQABTBDKT4GBgdnNYMcCBvsPUBlmIGYEyjMDISsDCwMbkAbx2IBsRgYOBj8GDwZJBnYgX4TBlmEdw2kGUQZ+BkYAnacH3g== 79.140,0.998,0.475,HISTIgAAAE142pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDAjACJRnApLsDMxgkoGBBchiA2JmBhEGHQZBoBgbAz+DL8Npht8M4gwCINUApvkH1A== 80.138,1.002,0.508,HISTIgAAAE542pNpmazIwMBgxwABTBDKT4GBgdnNYMcCBvsPDDDACIQsDMxAzMTACqSZgBgE2RjYgaQUgxaDIFhMnCGY4Q7DXQYJBn4gD6wTAMlCB90= 81.140,0.997,0.557,HISTIgAAAFB42pNpmazIwMDgwgABTBDKT4GBgdnNYMcCBvsPUBlWoBwjAzOQZAFCZiCbhYENyGOFimkz2DPwM/AB+dwMTgzHGJ4zCDDwgNXBACMA/WwH4w== 82.137,0.999,0.475,HISTIgAAAE542pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDDDACMZMQMjCwArEzAxsDJxgEWYgKc+gzsDHwA0UF2AIYrjK8IJBnIEfKMcIAKfXB9Y= 83.136,1.003,0.475,HISTIgAAAEx42pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPDAxwOUYgycrADIQscMwGFAexpBgUGbgZuBg4GAQZYhluMTxhEGYQAupgBACn3gfZ 84.139,1.001,0.492,HISTIgAAAEx42pNpmazIwMBgwwABTBDKT4GBgdnNYMcCBvsPDDDACIWsDMwMbGCVzGAeA5DHzCDBoMsgzMAB5MszeDI8ZLjCIMfAC1bBCAC31AfZ 85.140,0.996,0.442,HISTIgAAAEt42pNpmazIwMBgxgABTBDKT4GBgdnNYMcCBvsPUBl2IGQByrMCSTYGDiBkBfNYwSK8DG0M7gzCDJxAOX4GC4ZFDLMZRBg4AZVqB+U= 86.136,1.001,0.557,HISTIgAAAFF42pNpmazIwMDgwgABTBDKT4GBgdnNYMcCBvsPDAjACISsDCxAVSCSDUiD2MxAUTYGcQZNBiEgn5VBgiGU4Q7DYwYxBm6gDAMYg3UDAPppB+I= 87.137,0.999,0.541,HISTIgAAAE142pNpmazIwMDgxAABTBDKT4GBgdnNYMcCBvsPDAjACITMQDUsQJIVTLIAaRDJwiDMoAnEnAwcDCIMVgxXGP4ySDHwwMwD6QUA6PAH3Q== 88.136,1.002,0.475,HISTIgAAAE142pNpmazIwMBgxQABTBDKT4GBgdnNYMcCBvsPUBlGIGQCYxYGVgZ2IMkGxIwMzEAaREowaDLwM3AAebYM6ozdDE4MIkBVQF0An+EG3w== diskscan-0.21/hdrhistogram/test/jHiccup-2.0.7S.logV2.hlog000066400000000000000000000174741456470715000227500ustar00rootroot00000000000000#[Logged with jHiccup version 2.0.7-SNAPSHOT] #[Histogram log format version 1.2] #[StartTime: 1441812279.474 (seconds since epoch), Wed Sep 09 08:24:39 PDT 2015] "StartTimestamp","Interval_Length","Interval_Max","Interval_Compressed_Histogram" 0.127,1.007,2.769,HISTFAAAAEV42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPEBEJISEuATEZMQ4uASkhIR4nrxg9v2lMaxhvMekILGZkKmcCAEf2CsI= 1.134,0.999,0.442,HISTFAAAAEJ42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWLj45FTExAT4pBSEBKa6UkAgBi1uM7xjfMMlwMDABAC0CCjM= 2.133,1.001,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBE+Ph4OLgk5OSkeIS4+LgEeswIDo1+MbmdYNASYAA51CSo= 3.134,1.001,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBExPiEpITEFGTkRKSEeOR6FkCg1hTeMXvNYlHhYABQ5CTo= 4.135,0.997,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBE2PiERBREpBREhER4+Hj4uvQAdrTlMBldYDDhYAAugCKk= 5.132,1.002,0.426,HISTFAAAAEF42pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPEBEWPhElOR4pARUpKTkpGQkxq2mMegZnGI0+MZuIcAEAHo8Jvw== 6.134,0.999,0.442,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWIS4FITEhDiEJERE+GT6ZkhZGLbl7jEqrWHREmFgAIbAJMw== 7.133,0.999,0.459,HISTFAAAAEJ42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNEhEtMQEBBTk5MQERCRkBEQEWlh9FJbg9jE+MS5ig1LhYmADkkCcE= 8.132,1.000,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWIREgEOIQEuGT4xHg41Oo0pIqu8LYwVImwMfGBAAfkgkw 9.132,1.751,1551.892,HISTFAAAAJZ42pNpmSzMwMB0nQECmCCUnwIDA7ObwY4FDPYfYDJMXFxsbGwMbBwszDwsDDxsHFw6RWJMLJMZmcqBMJrJmskSiA2ZZJmkgRBCgmheIORGI1H5rEzMQAyDzFhY2EWRWUwMWCBxQtQQhAIWJiyAaEHyFbKwsLHAADYWAWmiFeKS5gACLsIEzdQICAgBIQShEfhFABXDF+M= 10.883,0.250,0.426,HISTFAAAAD142pNpmSzMwMAgxQABTBDKT4GBgdnNYMcCBvsPEBEeFi4mPg4WLhY2BjY2FhYOBSkpASEtoRA+NgDkCQZR 11.133,1.003,0.524,HISTFAAAAER42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPUBk2HgkZKREpEQUeGSEBAQ6xSYxhCnp7GJ02sWgJsbCwMgEAO0AJSQ== 12.136,0.997,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPUBk2AT4eCQURHgkuEREOHjERlSQhhWuMSV9Y7ERYWAAa4gko 13.133,0.998,0.459,HISTFAAAAD942pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPMBkRIR4RMRk5KQE+PgEhMRmzEjWZJ4whW1hMBNiYAB42CTA= 14.131,1.000,0.492,HISTFAAAAEN42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPUBkWFhE5GT4FKQkRCR4ZCREpqwmMBhpHGG16WHx42JgYmAA6swk+ 15.131,1.001,0.442,HISTFAAAAD542pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPMBkuMTEFHgklFRkRATkJERGdKgudfYwRTSwGalwAF2IJOw== 16.132,1.001,0.524,HISTFAAAAEZ42pNpmSzMwMCgxAABTBDKT4GBgdnNYMcCBvsPEBE2IQEFCQkpGREpHj4hKS6NU4z7GDMkuBoYDSYw2wiwMLEyAQBQ3wne 17.133,0.998,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPUBk2DjElIR4RHiExKQE5IT61iCodtXWMdn0sKVJMTAAekAk0 18.131,1.000,0.459,HISTFAAAAEF42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPUBkWISERJSUJESklHhEJEREhqwZGLakPjDZdLBYCHCwAKOkJPg== 19.131,1.000,0.475,HISTFAAAAEF42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPUAk2HjkJBSk+Pi4BMT4xIQE9pxIluTOMPhtYbITY2JgAKLoJOQ== 20.131,1.004,0.475,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBFmPhEJOSEhDi4+ETEeASEhswIVi1+MFjtYvCRYGJgAIP8JNw== 21.135,0.999,0.492,HISTFAAAAEB42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNMhk1AjINDRECAj4+Hi49LKS5CS2EGo1kXa4ANExMDEwAmOQil 22.134,0.997,0.459,HISTFAAAAEB42pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPEBFmHhE+MRExCTEZAS4RMQERvRI1hSuMTidY3KQ4mAAXhgks 23.131,1.004,0.508,HISTFAAAAEB42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNMhotHSEBASEyMg09MQUSIT6tKS2YKY8gfFj8tJmYmJgAsowkz 24.135,0.998,0.492,HISTFAAAAEJ42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPEBEBLjkhETEpET4BISEhCR6FsqAQFY1jjBoTWPQEOJiZAC2aCUY= 25.133,1.002,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPUBkuHh4BITEpMSEpLiE5AS6FoAgdpQuMJk9YzMRYmAAdngk2 26.135,0.998,0.508,HISTFAAAAER42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPUAkOKSEJKTUJOT4+IQkeIT69LYwVCnIbGI0eMZtJsTAxMwEAQvkJyg== 27.133,0.998,0.442,HISTFAAAAEN42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPEBE2CQUZFTkZOSURKQkRMT6NKYwhbYxaOocY/a4xSUmwAQA4pQpb 28.131,1.002,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBGtFDcHIy0jDQUdPjENFZUzjNNYHCT4uBQkzJiYADIGCcY= 29.133,1.460,968.884,HISTFAAAAJZ42pNpmSzMwMDUwgABTBDKT4GBgdnNYMcCBvsPEBE5AwMDJSUFISk2ETYuAS6PQ0xSXCzsTEw7GZnKgdCTyZLJGog1maSZZIFYGkpLMnEz8QIhOolgcTKxAiEzmGRFYxMShbEYUCAalzRBsjSjARYmTIBNjDKFSIIsIMDGAgPYWJRJE1DIxQEEaAQHF2GCNDVsAE2dFJE= 30.593,0.541,0.459,HISTFAAAAEB42pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPEBEFCxUNBRkFMTE+Pj4ZHgGHFYwGIkJcMiIpbEwMTAAdQQhJ 31.134,0.997,0.737,HISTFAAAAER42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPEJGAHsYexqKaIAcPPRMVKTEhoR6mJUxqfBx8LFwCTOxM0kwAfR8KqA== 32.131,1.002,0.508,HISTFAAAAEJ42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNEJKCDMcHJw8jOTUfNSEZGQuUb4x9GHxkJDg2hMA4WViYmAHWrC2k= 33.133,1.000,0.426,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBGXGK8QHS09PRM9BRMxBa55jBOY03REhByE3DhYADicCkc= 34.133,0.998,0.442,HISTFAAAAEB42pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPEBE1NzsfJwMVEw0pFS0hOZm4FqYKPy2FAoUJjFIsTAA/mQql 35.131,1.000,0.459,HISTFAAAAEN42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPEBERMy0jPTk5LRUFJQk1GamYdUzHGO0UxIrUljBKsbEwAQBKXgqU 36.131,1.001,0.557,HISTFAAAAEd42pNpmSzMwMCgygABTBDKT4GBgdnNYMcCBvsPEBExJzcNMyU5PRUpLSkJKYWwHqYWRjslkTKNC4wKHGwMTExArUwAi/IKnA== 37.132,1.002,0.442,HISTFAAAAEJ42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPEBEFLRsVPQkTKTkhPT4ZBTm3V4yTGD20pFoYtZqYxESYAEjICok= 38.134,1.000,0.803,HISTFAAAAEJ42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNERM7Hwk3LRslMSkZMQExDLGQL0yTGIC2pKJ1VjCwcTJpMAFufCso= 39.134,0.997,0.492,HISTFAAAAEN42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPEBE5Oz8DPRsFORM5FQkNKaGCA8wtjCoSfBYSTYxCLEBtTABiWgor 40.131,1.000,0.442,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBExJQUNFTElFRUZBRUZDTGfJqYKHzmhHka5ZUwSQmwANK0J+g== 41.131,1.002,0.475,HISTFAAAAEV42pNpmSzMwMCgyAABTBDKT4GBgdnNYMcCBvsPEBE2Hj45PiEFGSU5EQkpKREJuVmMLYwaWk8YQyYwa3CxMTABAEOgCdQ= 42.133,1.000,0.459,HISTFAAAAD942pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPMBk+Lg4+ER4hMT4hIT4lLh69OAOZZ4wOr1hCpFiYABjUCSY= 43.133,1.002,0.442,HISTFAAAAD942pNpmSzMwMAgwwABTBDKT4GBgdnNYMcCBvsPEBFmLgEJMTERHjEuCRERBSERoww5rRuMendYPFRYAA3tCTM= 44.135,0.998,0.590,HISTFAAAAEJ42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPUBk+FT0lJTktJSUjOTE1OQGpmnOMdnorGF3WMemxCTIBAEAhCnU= 45.133,0.998,0.442,HISTFAAAAEJ42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEWMS0DIyMFOSsNPTEFMSGNA4x+LxidfOp0VjBKcLAAAECLCv4= 46.131,1.004,0.442,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBEuMS0VEyMlLSkzGQUJOSkJj6RnjE56WxjNWpik2JgAO34KfQ== 47.135,0.996,0.475,HISTFAAAAEF42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNUgk2GR0ZOQkSAR4aLS0KKTyNtDqOWxjVGu2fMGlJMTEwANsIJvA== 48.131,1.950,1803.551,HISTFAAAAKF42pNpmSzMwMD0mQECmCCUnwIDA7ObwY4FDPYfICKsTExMLCysLCxsbEwMTAIsDHIsWTwsbNsZmcqZKpncmayZLIFYnUmWSRoMIbQkEy8TNxQjkwgWJxMrGDJDaews/KIMKBCNSytBZCYqYGHCBNjEiBckoJAFBNhYYADBwipIhkIC0lwcQIBGcHARJqigBkwKCQgICSAIFA75IlwAeB8ZpQ== 50.081,0.050,0.393,HISTFAAAADl42pNpmSzMwMAgxgABTBDKT4GBgdnNYMcCBvsPEBE2BiYWNiYWZiYGJiZmJg4OLiYuFiYWAMWGBSM= 50.131,1.001,0.442,HISTFAAAAEF42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBE2Lj4VAQkuJT45KTkOKSExI68eRgeDvB2MfcxxckwAJD8JyA== 51.132,0.999,0.459,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPUBk2NgUFGSkNAQEeJSkuKSmxhAojhZADjKuYiyS4WAAlWgm/ 52.131,1.002,0.557,HISTFAAAAER42pNpmSzMwMCgxAABTBDKT4GBgdnNYMcCBvsPUBkWPjEFGSMZKQMJJSEhPgkJiyodjZIHjB+YSvh4mBiYWJkAVc8KVw== 53.133,0.998,0.442,HISTFAAAAEJ42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBE2HjklJR0VPSUDHTUxJSkJs02MuxhtrLxKHjH6cbEAADjeCuw= 54.131,1.003,0.442,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPMBkNPzMLIw0NLQ0pFTERCTGLT4wpQSVbGFcwynExAQA/uwsC 55.134,0.997,0.426,HISTFAAAAD942pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPUBkWFTUjCy01BQ0VFRUJGSkJjRamiqA5jHmXGIV4ACoyCmo= 56.131,1.000,0.459,HISTFAAAAEF42pNpmSzMwMCgwAABTBDKD8hndjPYsYDB/gNUhk1FzsrAQElFQ0xCQkJOTEDnE6ObxwrGDsYuJjUODiYASN8KbA== 57.131,1.000,0.459,HISTFAAAAEF42pNpmSzMwMAgzwABTBDKT4GBgdnNYMcCBvsPMBk5FT0JAzUNKTklKQ0FMaGUJ4wJFjcYk+4wqnAwMAEAQooK6Q== 58.131,1.002,0.442,HISTFAAAAEB42pNpmSzMwMAgywABTBDKT4GBgdnNYMcCBvsPEBEuCRMNJwMlIzUtLR0ZMREZv6IHjFYGdUXLGE14WAA4OwsG 59.133,0.998,0.442,HISTFAAAAEB42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPMBklExUdIwcdFRUlOTMZPhWXB4wBTssYsy4xKnGwAQA8bAry 60.131,1.000,0.524,HISTFAAAAEJ42pNpmSzMwMAgxwABTBDKT4GBgdnNYMcCBvsPEBFmIRcjPR0bFR0lDSk5KQkZpXlMXkF5qxh3MMqIcDIBADy8CoE= 61.131,1.000,26.083,HISTFAAAAF542pNpmSzMwMAQyAABTBDKT4GBgdnNYMcCBvsPMBkFHSMrCzEZLSUFCSkJOTmTf4xRQW2MYT8Y5diYdjIylTNVMrkzWTJZA7EmkzQYykJpSSZeJm4ghpAQFgATDg85 diskscan-0.21/hdrhistogram/test/minunit.h000066400000000000000000000026631456470715000205610ustar00rootroot00000000000000/** * minunit.h * Written by Michael Barker and released to the public domain, * as explained at http://creativecommons.org/publicdomain/zero/1.0/ */ #ifndef MINUNIT_H #define MINUNIT_H #include #include struct mu_result { char* test; char* message; }; #define mu_assert(message, test) \ do { \ if (!(test)) \ return message; \ } while (0) #define mu_run_test(name) \ do { \ char *message = name(); \ tests_run++; \ if (message) { \ struct mu_result r; \ r.test = #name; \ r.message = message; \ return r; \ } \ } while (0) #define mu_ok \ do { \ struct mu_result r; \ r.test = 0; \ r.message = 0; \ return r; \ } while (0) extern int tests_run; static bool compare_double(double a, double b, double delta) { if (fabs(a - b) < delta) { return true; } printf("[compare_double] fabs(%f, %f) < %f == false\n", a, b, delta); return false; } static bool compare_int64(int64_t a, int64_t b) { if (a == b) { return true; } printf("[compare_int64] %" PRIu64 " == %" PRIu64 " == false\n", a, b); return false; } #endif diskscan-0.21/include/000077500000000000000000000000001456470715000146675ustar00rootroot00000000000000diskscan-0.21/include/arch.h000066400000000000000000000042661456470715000157650ustar00rootroot00000000000000#ifndef _DISKSCAN_ARCH_H #define _DISKSCAN_ARCH_H #include "libscsicmd/include/scsicmd.h" #include #include #include typedef struct disk_dev_t disk_dev_t; typedef struct { enum result_data_e { DATA_FULL, /* All data received for the request */ DATA_PARTIAL, /* Only some of the data was received/sent */ DATA_NONE /* No data was received/sent */ } data; enum result_error_e { ERROR_NONE, /* No error encountered */ ERROR_CORRECTED, /* A corrected error encountered */ ERROR_UNCORRECTED, /* Unocrrected but non-fatal (i.e. local) error */ ERROR_NEED_RETRY, /* Temporary error that only merits a retry to complete */ ERROR_FATAL, /* A fatal error encountered, no reason to continue using disk */ ERROR_UNKNOWN, /* An unknown error encountered, continue for a while unless it persists */ } error; sense_info_t info; unsigned char sense[256]; unsigned sense_len; } io_result_t; typedef enum { DISK_NOT_MOUNTED = 0, DISK_MOUNTED_RO = 1, DISK_MOUNTED_RW = 2, } disk_mount_e; disk_mount_e disk_dev_mount_state(const char *path); bool disk_dev_open(disk_dev_t *dev, const char *path); void disk_dev_close(disk_dev_t *dev); void disk_dev_cdb_out(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, unsigned char *sense, unsigned sense_size, unsigned *sense_read, io_result_t *io_res); void disk_dev_cdb_in(disk_dev_t *dev, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_size, unsigned *buf_read, unsigned char *sense, unsigned sense_size, unsigned *sense_read, io_result_t *io_res); ssize_t disk_dev_read(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res); ssize_t disk_dev_write(disk_dev_t *dev, uint64_t offset_bytes, uint32_t len_bytes, void *buf, io_result_t *io_res); int disk_dev_read_cap(disk_dev_t *dev, uint64_t *size_bytes, uint64_t *sector_size); int disk_dev_identify(disk_dev_t *dev, char *vendor, char *model, char *fw_rev, char *serial, bool *is_ata, unsigned char *ata_buf, unsigned *ata_buf_len); void mac_read(unsigned char *buf, int len); #include "arch-internal.h" #endif diskscan-0.21/include/cli.h000066400000000000000000000001341456470715000156050ustar00rootroot00000000000000#ifndef DISKSCAN_CLI #define DISKSCAN_CLI int diskscan_cli(int argc, char **argv); #endif diskscan-0.21/include/compiler.h000066400000000000000000000002541456470715000166530ustar00rootroot00000000000000#ifndef _COMPILER_H #define _COMPILER_H #ifdef __GNUC__ # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) #else # define UNUSED(x) UNUSED_ ## x #endif #endif diskscan-0.21/include/disk.h000066400000000000000000000010071456470715000157700ustar00rootroot00000000000000#ifndef DISKSCAN_DISK_H #define DISKSCAN_DISK_H #include "arch.h" #include "libscsicmd/include/ata.h" /** Check if the disk had a smart trip, only relevant for ATA disks. * * Returns -1 on error, 0 if there is no smart trip and 1 if there is a smart trip. */ int disk_smart_trip(disk_dev_t *dev); /** Read the disk SMART attributes into the pre-defined array. * Returns -1 on error, number of attributes on success. */ int disk_smart_attributes(disk_dev_t *dev, ata_smart_attr_t *attrs, int max_attrs); #endif diskscan-0.21/include/diskscan.h000066400000000000000000000053431456470715000166440ustar00rootroot00000000000000#ifndef _DISKSCAN_H_ #define _DISKSCAN_H_ #include #include #include "arch.h" #include "libscsicmd/include/ata.h" #include "hdrhistogram/src/hdr_histogram.h" #define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0])) enum scan_mode { SCAN_MODE_UNKNOWN, SCAN_MODE_SEQ, SCAN_MODE_RANDOM, }; enum conclusion { CONCLUSION_SCAN_PROBLEM, /* Problem in the scan, no real conclusion */ CONCLUSION_ABORTED, /* Scan aborted by used */ CONCLUSION_PASSED, /* Disk looks fine */ /* Disk looks bad, and the reason it failed the test */ CONCLUSION_FAILED_MAX_LATENCY, CONCLUSION_FAILED_LATENCY_PERCENTILE, CONCLUSION_FAILED_IO_ERRORS, }; typedef struct latency_t { uint64_t start_sector; uint64_t end_sector; uint32_t latency_min_msec; uint32_t latency_max_msec; uint32_t latency_median_msec; } latency_t; typedef struct data_log_raw_t { FILE *f; bool is_first; } data_log_raw_t; typedef struct data_log_t { FILE *f; bool is_first; } data_log_t; typedef struct ata_state_t { bool is_smart_tripped; const struct smart_table *smart_table; ata_smart_attr_t smart[MAX_SMART_ATTRS]; int smart_num; int last_temp; int last_reallocs; int last_pending_reallocs; int last_crc_errors; } ata_state_t; typedef struct scsi_state_t { } scsi_state_t; typedef struct disk_t { disk_dev_t dev; char path[128]; char vendor[64]; char model[64]; char fw_rev[64]; char serial[64]; bool is_ata; union { ata_state_t ata; scsi_state_t scsi; } state; unsigned char ata_buf[512]; unsigned ata_buf_len; uint64_t num_bytes; uint64_t sector_size; int run; int fix; uint64_t num_errors; struct hdr_histogram *histogram; unsigned latency_graph_len; latency_t *latency_graph; enum conclusion conclusion; data_log_raw_t data_raw; data_log_t data_log; } disk_t; int disk_open(disk_t *disk, const char *path, int fix, unsigned latency_graph_len, disk_mount_e allowed_mount); int disk_scan(disk_t *disk, enum scan_mode mode, unsigned data_size); int disk_close(disk_t *disk); void disk_scan_stop(disk_t *disk); enum scan_mode str_to_scan_mode(const char *s); const char *conclusion_to_str(enum conclusion conclusion); /* Implemented by the user (gui/cli) */ void report_progress(disk_t *disk, int percent_part, int percent_full); void report_scan_success(disk_t *disk, uint64_t offset_bytes, uint64_t data_size, uint64_t time); void report_scan_error(disk_t *disk, uint64_t offset_bytes, uint64_t data_size, uint64_t time); void report_scan_done(disk_t *disk); /* Used to log data to files */ void data_log_raw_start(data_log_raw_t *log_raw, const char *filename, disk_t *disk); void data_log_raw_end(data_log_raw_t *log_raw); void data_log_start(data_log_t *log, const char *filename, disk_t *disk); void data_log_end(data_log_t *log, disk_t *disk); #endif diskscan-0.21/include/median.h000066400000000000000000000031271456470715000163000ustar00rootroot00000000000000#ifndef _MEDIAN_H #define _MEDIAN_H /* This is taken from http://ndevilla.free.fr/median/median/src/wirth.c */ /* * Algorithm from N. Wirth's book, implementation by N. Devillard. * This code in public domain. */ #include #define elem_type uint32_t #define ELEM_SWAP(a,b) { register elem_type t=(a);(a)=(b);(b)=t; } /*--------------------------------------------------------------------------- Function : kth_smallest() In : array of elements, # of elements in the array, rank k Out : one element Job : find the kth smallest element in the array Notice : use the median() macro defined below to get the median. Reference: Author: Wirth, Niklaus Title: Algorithms + data structures = programs Publisher: Englewood Cliffs: Prentice-Hall, 1976 Physical description: 366 p. Series: Prentice-Hall Series in Automatic Computation ---------------------------------------------------------------------------*/ static elem_type kth_smallest(elem_type a[], int n, int k) { register int i,j,l,m ; register elem_type x ; l=0 ; m=n-1 ; while (l 0) verbose_out("V: " __VA_ARGS__) #define VVERBOSE(...) if (verbose > 1) verbose_out("V: " __VA_ARGS__) #define VVVERBOSE(...) if (verbose > 2) verbose_out("V: " __VA_ARGS__) #define INFO(...) verbose_out("I: " __VA_ARGS__) #define ERROR(...) verbose_out("E: " __VA_ARGS__) #endif diskscan-0.21/lib/000077500000000000000000000000001456470715000140125ustar00rootroot00000000000000diskscan-0.21/lib/data.c000066400000000000000000000214121456470715000150670ustar00rootroot00000000000000/* * Copyright 2013 Baruch Even * * This file is part of DiskScan. * * DiskScan is free software: 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 3 of the License, or * (at your option) any later version. * * DiskScan is distributed in the hope that 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 DiskScan. If not, see . * */ #include "diskscan.h" #include "data.h" #include "compiler.h" #include "system_id.h" #include "hdrhistogram/src/hdr_histogram_log.h" #include #include #include #include #include static const char *result_data_to_name(enum result_data_e data) { switch (data) { case DATA_FULL: return "data_full"; case DATA_PARTIAL: return "data_partial"; case DATA_NONE: return "data_none"; } return "data_unknown"; } static const char *result_error_to_name(enum result_error_e error) { switch (error) { case ERROR_NONE: return "error_none"; case ERROR_CORRECTED: return "error_corrected"; case ERROR_UNCORRECTED: return "error_uncorrected"; case ERROR_NEED_RETRY: return "error_need_retry"; case ERROR_FATAL: return "error_fatal"; case ERROR_UNKNOWN: return "error_unknown"; } return "error_unknown"; } static inline char nibble_to_hex(unsigned char nibble) { if (nibble < 10) return '0' + nibble; else return 'A' + nibble - 10; } static inline void buf_to_hex(unsigned char *buf, unsigned buf_len, unsigned char *out_buf, unsigned out_buf_len) { for (; buf_len > 0 && out_buf_len >= 3; buf_len--, out_buf_len -= 2) { *(out_buf++) = nibble_to_hex(*buf >> 4); *(out_buf++) = nibble_to_hex(*buf & 0x0F); buf++; } *out_buf = 0; } static void system_identifier_to_json(system_identifier_t *system_id, char *buf, int buf_len) { int len = snprintf(buf, buf_len, "{ \"System\": \"%s\", \"Chassis\": \"%s\", \"BaseBoard\": \"%s\", \"Mac\": \"%s\", \"OS\": \"%s\" }", system_id->system, system_id->chassis, system_id->baseboard, system_id->mac, system_id->os); // If we failed we should at least keep it a valid json if (len >= buf_len || len <= 0) snprintf(buf, buf_len, "{}"); } static void system_id_output(FILE *f) { char buf[2048]; system_identifier_t system_id; memset(&system_id, 0, sizeof(system_id)); if (system_identifier_read(&system_id)) { system_identifier_to_json(&system_id, buf, sizeof(buf)); fputs(buf, f); } else { fputs("{}", f); } } static const char *sense_info_to_json(struct sense_info_t *info, unsigned char *sense, unsigned sense_len) { static char buf[2048]; unsigned char sense_hex[sizeof(sense) * 2 + 1]; buf_to_hex(sense, sense_len, sense_hex, sizeof(sense_hex)); snprintf(buf, 2048, "{\"SenseKey\": %u, \"Asc\": %u, \"Ascq\": %u, \"FruCode\": %u, \"VendorCode\": %u, \"Hex\": \"%s\"}", info->sense_key, info->asc, info->ascq, info->fru_code_valid ? info->fru_code : 0, info->vendor_unique_error, sense_hex); // bool ata_status_valid; // ata_status_t ata_status; return buf; } static inline void add_indent(FILE *f, int indent) { int i; for (i = 0; i < indent*4; i++) fprintf(f, " "); } static void disk_output(FILE *f, disk_t *disk, int indent) { fprintf(f, "{\n"); add_indent(f, indent); fprintf(f, "\"Vendor\": \"%s\",\n", disk->vendor); add_indent(f, indent); fprintf(f, "\"Model\": \"%s\",\n", disk->model); add_indent(f, indent); fprintf(f, "\"FwRev\": \"%s\",\n", disk->fw_rev); add_indent(f, indent); fprintf(f, "\"Serial\": \"%s\",\n", disk->serial); add_indent(f, indent); fprintf(f, "\"NumSectors\": %"PRIu64",\n", disk->num_bytes / disk->sector_size); add_indent(f, indent); fprintf(f, "\"SectorSize\": %"PRIu64",\n", disk->sector_size); if (disk->is_ata && disk->ata_buf_len > 0) { unsigned char ata_hex[512*2+1]; buf_to_hex(disk->ata_buf, disk->ata_buf_len, ata_hex, sizeof(ata_hex)); add_indent(f, indent); fprintf(f, "\"AtaIdentifyRaw\": \"%s\"\n", ata_hex); } add_indent(f, indent); fprintf(f, "}"); } static void data_log_event(FILE *f, int indent, uint64_t lba, uint32_t len, io_result_t *io_res, uint32_t t_nsec) { add_indent(f, indent); fprintf(f, "{\"LBA\": %16"PRIu64", \"Len\": %8u, \"LatencyNSec\": %8u, ", lba, len, t_nsec); fprintf(f, "\"Data\": \"%s\", ", result_data_to_name(io_res->data)); fprintf(f, "\"Error\": \"%s\", ", result_error_to_name(io_res->error)); fprintf(f, "\"Sense\": %s", sense_info_to_json(&io_res->info, io_res->sense, io_res->sense_len)); fprintf(f, "}"); } void data_log_raw_start(data_log_raw_t *log_raw, const char *filename, disk_t *disk) { log_raw->f = fopen(filename, "wt"); if (log_raw->f == NULL) return; log_raw->is_first = true; fprintf(log_raw->f, "{\n"); // Information about the disk itself add_indent(log_raw->f, 1); fprintf(log_raw->f, "\"Disk\": "); disk_output(log_raw->f, disk, 2); fprintf(log_raw->f, ",\n"); add_indent(log_raw->f, 1); fprintf(log_raw->f, "\"Raw\": [\n"); } void data_log_raw_end(data_log_raw_t *log_raw) { fprintf(log_raw->f, "\n"); // End the line we left open from data_log_raw add_indent(log_raw->f, 1); fprintf(log_raw->f, "]\n"); // Close the raw log array fprintf(log_raw->f, "}\n"); // Close the entire struct fclose(log_raw->f); } void data_log_raw(data_log_raw_t *log_raw, uint64_t lba, uint32_t len, io_result_t *io_res, uint32_t t_nsec) { if (log_raw == NULL || log_raw->f == NULL) return; if (!log_raw->is_first) fprintf(log_raw->f, ",\n"); else log_raw->is_first = false; data_log_event(log_raw->f, 2, lba, len, io_res, t_nsec); } static void time_output(FILE *f, const char *name) { char now[64]; time_t t; struct tm *tmp; t = time(NULL); tmp = gmtime(&t); if (tmp != NULL) strftime(now, sizeof(now), "%Y-%m-%d %H:%M:%S", tmp); else snprintf(now, sizeof(now), "%"PRIu64, (uint64_t)t); fprintf(f, "\"%s\": \"%s\"", name, now); } void data_log_start(data_log_t *log, const char *filename, disk_t *disk) { log->f = fopen(filename, "wt"); if (!log->f) return; log->is_first = true; fprintf(log->f, "{\n"); add_indent(log->f, 1); fprintf(log->f, "\"Disk\": "); disk_output(log->f, disk, 2); fprintf(log->f, ",\n"); add_indent(log->f, 1); fprintf(log->f, "\"Machine\": "); system_id_output(log->f); fprintf(log->f, ",\n"); // TODO: Output Disk mode page info // TODO: Output Disk SATA configuration add_indent(log->f, 1); fprintf(log->f, "\"Scan\": {\n"); add_indent(log->f, 2); time_output(log->f, "StartTime"); fprintf(log->f, ",\n"); add_indent(log->f, 2); fprintf(log->f, "\"Events\": [\n"); } static void histogram_output(FILE *f, struct hdr_histogram *histogram, int indent) { char *encoded_histogram; hdr_log_encode(histogram, &encoded_histogram); add_indent(f, indent); fprintf(f, "\"Histogram\": \"%s\",\n", encoded_histogram); free(encoded_histogram); } static void latency_output(FILE *f, latency_t *latency, int latency_len, int indent) { //unsigned latency_graph_len; //latency_t *latency_graph; add_indent(f, indent); fprintf(f, "\"Latencies\": [\n"); int i; for (i = 0; i < latency_len; i++) { if (i != 0) fprintf(f, ",\n"); add_indent(f, indent+1); fprintf(f, "{"); fprintf(f, "\"StartSector\": %16"PRIu64, latency[i].start_sector); fprintf(f, ", \"EndSector\": %16"PRIu64, latency[i].end_sector); fprintf(f, ", \"LatencyMinMsec\": %8u", latency[i].latency_min_msec); fprintf(f, ", \"LatencyMaxMsec\": %8u", latency[i].latency_max_msec); fprintf(f, ", \"LatencyMedianMsec\": %8u", latency[i].latency_median_msec); fprintf(f, "}"); } fprintf(f, "\n"); add_indent(f, indent); fprintf(f, "],\n"); } void data_log_end(data_log_t *log, disk_t *disk) { if (log == NULL || log->f == NULL) return; fprintf(log->f, "\n"); add_indent(log->f, 2); fprintf(log->f, "],\n"); // TODO: Output SMART Information // TODO: Output Log Page information add_indent(log->f, 2); time_output(log->f, "EndTime"); fprintf(log->f, ",\n"); histogram_output(log->f, disk->histogram, 2); latency_output(log->f, disk->latency_graph, disk->latency_graph_len, 2); add_indent(log->f, 2); fprintf(log->f, "\"Conclusion\": \"%s\"\n", conclusion_to_str(disk->conclusion)); add_indent(log->f, 1); fprintf(log->f, "}\n"); fprintf(log->f, "}\n"); } void data_log(data_log_t *log, uint64_t lba, uint32_t len, io_result_t *io_res, uint32_t t_nsec) { if (log == NULL || log->f == NULL) return; if (io_res->data != DATA_FULL || io_res->error != ERROR_NONE || t_nsec > 1000*1000*1000) { if (!log->is_first) fprintf(log->f, ",\n"); else log->is_first = false; data_log_event(log->f, 3, lba, len, io_res, t_nsec); } } diskscan-0.21/lib/data.h000066400000000000000000000004341456470715000150750ustar00rootroot00000000000000#ifndef DISKSCAN_DATA_H #define DISKSCAN_DATA_H #include "arch.h" void data_log(data_log_t *log, uint64_t lba, uint32_t len, io_result_t *io_res, uint32_t t_nsec); void data_log_raw(data_log_raw_t *log_raw, uint64_t lba, uint32_t len, io_result_t *io_res, uint32_t t_nsec); #endif diskscan-0.21/lib/disk.c000066400000000000000000000021171456470715000151110ustar00rootroot00000000000000#include "disk.h" #include "libscsicmd/include/ata.h" int disk_smart_trip(disk_dev_t *dev) { int cdb_len; unsigned char cdb[32]; unsigned char buf[512]; unsigned char sense[128]; unsigned buf_read = 0; unsigned sense_read = 0; io_result_t io_res; bool smart_ok; cdb_len = cdb_ata_smart_return_status(cdb); disk_dev_cdb_in(dev, cdb, cdb_len, buf, sizeof(buf), &buf_read, sense, sizeof(sense), &sense_read, &io_res); if (!ata_smart_return_status_result(sense, sense_read, &smart_ok)) return -1; return smart_ok ? 0 : 1; } int disk_smart_attributes(disk_dev_t *dev, ata_smart_attr_t *attrs, int max_attrs) { int cdb_len; unsigned char cdb[32]; unsigned char buf[512]; unsigned char sense[128]; unsigned buf_read = 0; unsigned sense_read = 0; io_result_t io_res; cdb_len = cdb_ata_smart_read_data(cdb); disk_dev_cdb_in(dev, cdb, cdb_len, buf, sizeof(buf), &buf_read, sense, sizeof(sense), &sense_read, &io_res); // TODO: Need to report about the SMART failure, once. if (io_res.data != DATA_FULL) return -1; return ata_parse_ata_smart_read_data(buf, attrs, max_attrs); } diskscan-0.21/lib/diskscan.c000066400000000000000000000563561456470715000157740ustar00rootroot00000000000000/* * Copyright 2013 Baruch Even * * This file is part of DiskScan. * * DiskScan is free software: 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 3 of the License, or * (at your option) any later version. * * DiskScan is distributed in the hope that 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 DiskScan. If not, see . * */ #include "diskscan.h" #include "verbose.h" #include "disk.h" #include "arch.h" #include "median.h" #include "compiler.h" #include "data.h" #include "libscsicmd/include/smartdb.h" #include "libscsicmd/include/ata_smart.h" #include #include #include #include #include #include #include #include #include #include #include #include #define TEMP_THRESHOLD 65 struct scan_state { uint32_t latency_bucket; uint64_t latency_stride; uint32_t latency_count; uint32_t *latency; void *data; uint64_t progress_bytes; int progress_part; int progress_full; unsigned num_unknown_errors; }; typedef int spinner_t; static char spinner_form[] = {'|', '/', '-', '\\', '|', '/', '-', '\\'}; static void spinner_init(spinner_t *spinner) { printf("%c\r", spinner_form[0]); *spinner = 1; fflush(stdout); } static void spinner_update(spinner_t *spinner) { printf("\r%c\r", spinner_form[*spinner]); if (++(*spinner) == ARRAY_SIZE(spinner_form)) *spinner = 0; fflush(stdout); } static void spinner_done(void) { printf("\r \r"); fflush(stdout); } const char *conclusion_to_str(enum conclusion conclusion) { switch (conclusion) { case CONCLUSION_FAILED_IO_ERRORS: return "failed due to IO errors"; case CONCLUSION_FAILED_MAX_LATENCY: return "failed due to a high max latency"; case CONCLUSION_FAILED_LATENCY_PERCENTILE: return "failed to to a high latency in the 99.99%'ile"; case CONCLUSION_PASSED: return "passed"; case CONCLUSION_SCAN_PROBLEM: return "scan_problem"; case CONCLUSION_ABORTED: return "scan_aborted"; } return "unknown"; } enum scan_mode str_to_scan_mode(const char *s) { if (strcasecmp(s, "seq") == 0 || strcasecmp(s, "sequential") == 0) return SCAN_MODE_SEQ; if (strcasecmp(s, "random") == 0) return SCAN_MODE_RANDOM; return SCAN_MODE_UNKNOWN; } static void disk_ata_monitor_start(disk_t *disk) { if (disk_smart_trip(&disk->dev) == 1) { ERROR("Disk has a SMART TRIP at the start of the test, it should be discarded anyhow"); disk->state.ata.is_smart_tripped = true; } else { disk->state.ata.is_smart_tripped = false; } disk->state.ata.smart_table = smart_table_for_disk(disk->vendor, disk->model, disk->fw_rev); if (disk->state.ata.smart_table == NULL) ERROR("BUG! Failed to setup smart table for the disk."); disk->state.ata.smart_num = disk_smart_attributes(&disk->dev, disk->state.ata.smart, ARRAY_SIZE(disk->state.ata.smart)); if (disk->state.ata.smart_num > 0) { // First look at temperatures int min_temp = -1; int max_temp = -1; int temp = ata_smart_get_temperature(disk->state.ata.smart, disk->state.ata.smart_num, disk->state.ata.smart_table, &min_temp, &max_temp); disk->state.ata.last_temp = temp; if (min_temp > 0 || max_temp > 0) INFO("Disk start temperature is %d (lifetime min %d and lifetime max %d)", temp, min_temp, max_temp); else INFO("Disk start temperature is %d", temp); // First look on reallocations disk->state.ata.last_reallocs = ata_smart_get_num_reallocations(disk->state.ata.smart, disk->state.ata.smart_num, disk->state.ata.smart_table); disk->state.ata.last_pending_reallocs = ata_smart_get_num_pending_reallocations(disk->state.ata.smart, disk->state.ata.smart_num, disk->state.ata.smart_table); // Now take a first look at the CRC error counters disk->state.ata.last_crc_errors = ata_smart_get_num_crc_errors(disk->state.ata.smart, disk->state.ata.smart_num, disk->state.ata.smart_table); } else { ERROR("Failed to read SMART attributes from device"); } } static void ata_test_temp(disk_t *disk, ata_smart_attr_t *smart, int smart_num) { int min_temp = -1; int max_temp = -1; int temp = ata_smart_get_temperature(smart, smart_num, disk->state.ata.smart_table, &min_temp, &max_temp); if (temp != disk->state.ata.last_temp) { INFO("Disk temperature changed from %d to %d", disk->state.ata.last_temp, temp); disk->state.ata.last_temp = temp; } if (temp >= TEMP_THRESHOLD) { spinner_t spinner; INFO("Pausing scan due to high disk temperature"); spinner_init(&spinner); while (temp >= TEMP_THRESHOLD) { sleep(1); spinner_update(&spinner); smart_num = disk_smart_attributes(&disk->dev, smart, smart_num); if (smart_num > 0) { temp = ata_smart_get_temperature(smart, smart_num, disk->state.ata.smart_table, &min_temp, &max_temp); } else { ERROR("Failed to read temperature while paused!"); break; } } spinner_done(); INFO("Finished pause, temperature is now %d", temp); } } static void ata_test_reallocs(disk_t *disk, ata_smart_attr_t *smart, int smart_num) { int num_reallocs; int num_pending_reallocs; num_reallocs = ata_smart_get_num_reallocations(smart, smart_num, disk->state.ata.smart_table); num_pending_reallocs = ata_smart_get_num_pending_reallocations(smart, smart_num, disk->state.ata.smart_table); if (num_reallocs > disk->state.ata.last_reallocs) { INFO("Number of reallocated sectors increased from %d to %d\n", disk->state.ata.last_reallocs, num_reallocs); disk->state.ata.last_reallocs = num_reallocs; } if (num_pending_reallocs != disk->state.ata.last_pending_reallocs) { INFO("Number of pending sectors for reallocations changed from %d to %d\n", disk->state.ata.last_pending_reallocs, num_pending_reallocs); disk->state.ata.last_pending_reallocs = num_pending_reallocs; } } static void ata_test_crc_errors(disk_t *disk, ata_smart_attr_t *smart, int smart_num) { int crc_errors; crc_errors = ata_smart_get_num_crc_errors(smart, smart_num, disk->state.ata.smart_table); if (crc_errors != disk->state.ata.last_crc_errors) { ERROR("CRC errors increased from %d to %d, your problem is not the disk but in a cable most likely!", disk->state.ata.last_crc_errors, crc_errors); disk->state.ata.last_crc_errors = crc_errors; } } static void disk_ata_monitor(disk_t *disk) { ata_smart_attr_t smart[MAX_SMART_ATTRS]; int smart_num; if (!disk->state.ata.is_smart_tripped && disk_smart_trip(&disk->dev) == 1) { ERROR("Disk has a SMART TRIP in the middle of the test, it should be discarded!"); disk->state.ata.is_smart_tripped = true; } smart_num = disk_smart_attributes(&disk->dev, smart, ARRAY_SIZE(smart)); if (smart_num > 0) { ata_test_temp(disk, smart, smart_num); ata_test_reallocs(disk, smart, smart_num); ata_test_crc_errors(disk, smart, smart_num); } else { ERROR("Failed to read SMART attributes from device"); } } static void disk_ata_monitor_end(disk_t *disk) { ata_smart_attr_t smart[MAX_SMART_ATTRS]; int smart_num; int num_reallocs; int num_pending_reallocs; if (disk_smart_trip(&disk->dev) == 1) { ERROR("Disk has a SMART TRIP at the end of the test, it should be discarded!"); } else if (disk->state.ata.is_smart_tripped) { ERROR("Disk had a SMART TRIP during the test but it disappeared. This is super weird!!!"); } smart_num = disk_smart_attributes(&disk->dev, smart, ARRAY_SIZE(smart)); num_reallocs = ata_smart_get_num_reallocations(smart, smart_num, disk->state.ata.smart_table); num_pending_reallocs = ata_smart_get_num_pending_reallocations(smart, smart_num, disk->state.ata.smart_table); if (num_pending_reallocs > 0) { INFO("At the end of the test there are still some sectors pending reallocation, this is rather unexpected but can be lived with."); } if (num_reallocs > 1000) { INFO("Number of reallocated sectors is above 1000, you should probably stop using this disk!"); } } static void disk_scsi_monitor_start(disk_t *disk) { (void)disk; } static void disk_scsi_monitor(disk_t *disk) { (void)disk; } static void disk_scsi_monitor_end(disk_t *disk) { (void)disk; } static const char *disk_mount_str(disk_mount_e mount) { switch (mount) { case DISK_NOT_MOUNTED: return "not mounted"; case DISK_MOUNTED_RO: return "mounted read-only"; case DISK_MOUNTED_RW: return "mounted read-write"; default: return "unknown"; } } static int disk_mount_allowed(const char *path, disk_mount_e allowed_mount) { const disk_mount_e mount_state = disk_dev_mount_state(path); if (mount_state > allowed_mount) { ERROR("Disk is currently %s and we only allow %s, use --force-mounted or --force-mounted-rw if the risk of problems is acceptable", disk_mount_str(mount_state), disk_mount_str(allowed_mount)); return 0; } if (mount_state != DISK_NOT_MOUNTED) { INFO("Disk is %s but this is allowed with a force option", disk_mount_str(mount_state)); } return 1; } int disk_open(disk_t *disk, const char *path, int fix, unsigned latency_graph_len, disk_mount_e allowed_mount) { memset(disk, 0, sizeof(*disk)); disk->fix = fix; INFO("Validating path %s", path); if (access(path, F_OK)) { ERROR("Disk path %s does not exist, errno=%d: %s", path, errno, strerror(errno)); return 1; } const int access_mode_flag = fix ? R_OK|W_OK : R_OK; if (access(path, access_mode_flag)) { ERROR("Disk path %s is inaccessible, errno=%d: %s", path, errno, strerror(errno)); return 1; } if (fix && !disk_mount_allowed(path, allowed_mount)) { ERROR("Better not fix with the disk mounted, mounted fs may get confused when data is possibly modified under its feet"); return 1; } if (!disk_dev_open(&disk->dev, path)) { ERROR("Failed to open path %s, errno=%d: %s", path, errno, strerror(errno)); return 1; } if (disk_dev_read_cap(&disk->dev, &disk->num_bytes, &disk->sector_size) < 0) { ERROR("Can't get block device size information for path %s, errno=%d: %s", path, errno, strerror(errno)); goto Error; } if (disk->num_bytes == 0) { ERROR("Invalid number of sectors"); goto Error; } if (disk->sector_size == 0 || disk->sector_size % 512 != 0) { ERROR("Invalid sector size %" PRIu64, disk->sector_size); goto Error; } #if 0 const uint64_t new_bytes_raw = disk->num_bytes / 10; const uint64_t new_bytes_leftover = new_bytes_raw % 512; const uint64_t new_bytes = new_bytes_raw - new_bytes_leftover; disk->num_bytes = new_bytes; #endif if (disk_dev_identify(&disk->dev, disk->vendor, disk->model, disk->fw_rev, disk->serial, &disk->is_ata, disk->ata_buf, &disk->ata_buf_len) < 0) { ERROR("Can't identify disk for path %s, errno=%d: %s", path, errno, strerror(errno)); goto Error; } strncpy(disk->path, path, sizeof(disk->path)); disk->path[sizeof(disk->path)-1] = 0; hdr_init(1, 60*1000*1000, 3, &disk->histogram); disk->latency_graph_len = latency_graph_len; disk->latency_graph = calloc(latency_graph_len, sizeof(latency_t)); if (disk->latency_graph == NULL) { ERROR("Failed to allocate memory for latency graph data"); goto Error; } if (disk->is_ata) disk_ata_monitor_start(disk); else disk_scsi_monitor_start(disk); INFO("Opened disk %s sector size %"PRIu64" num bytes %"PRIu64, path, disk->sector_size, disk->num_bytes); return 0; Error: disk_close(disk); return 1; } int disk_close(disk_t *disk) { if (disk->is_ata) disk_ata_monitor_end(disk); else disk_scsi_monitor_end(disk); INFO("Closed disk %s", disk->path); disk_dev_close(&disk->dev); if (disk->latency_graph) { free(disk->latency_graph); disk->latency_graph = NULL; } return 0; } void disk_scan_stop(disk_t *disk) { disk->run = 0; } static void *allocate_buffer(int buf_size) { void *buf = mmap(NULL, buf_size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0); if (!buf) return NULL; return buf; } static void free_buffer(void *buf, int buf_size) { munmap(buf, buf_size); } static void latency_bucket_prepare(disk_t *disk, struct scan_state *state, uint64_t offset) { assert(state->latency_bucket < disk->latency_graph_len); latency_t *l = &disk->latency_graph[state->latency_bucket]; const uint64_t start_sector = offset / disk->sector_size; VVERBOSE("bucket prepare bucket=%u", state->latency_bucket); l->start_sector = start_sector; l->latency_min_msec = UINT32_MAX; state->latency_count = 0; } static void latency_bucket_finish(disk_t *disk, struct scan_state *state, uint64_t offset) { latency_t *l = &disk->latency_graph[state->latency_bucket]; const uint64_t end_sector = offset / disk->sector_size; VVERBOSE("bucket finish bucket=%d", state->latency_bucket); l->end_sector = end_sector; l->latency_median_msec = median(state->latency, state->latency_count); state->latency_count = 0; state->latency_bucket++; } static void latency_bucket_add(disk_t *disk, uint64_t latency, struct scan_state *state) { latency_t *l = &disk->latency_graph[state->latency_bucket]; if (latency < l->latency_min_msec) l->latency_min_msec = latency; if (l->latency_max_msec < latency) l->latency_max_msec = latency; // Collect info for median calculation later state->latency[state->latency_count++] = latency; } static const char *error_to_str(enum result_error_e err) { switch (err) { case ERROR_NONE: return "none"; case ERROR_CORRECTED: return "corrected"; case ERROR_UNCORRECTED: return "uncorrected"; case ERROR_NEED_RETRY: return "need_retry"; case ERROR_FATAL: return "fatal"; case ERROR_UNKNOWN: return "unknown"; } return "unknown"; } static const char *data_to_str(enum result_data_e data) { switch (data) { case DATA_FULL: return "full"; case DATA_PARTIAL: return "partial"; case DATA_NONE: return "none"; } return "unknown"; } static bool disk_scan_part(disk_t *disk, uint64_t offset, void *data, int data_size, struct scan_state *state) { ssize_t ret; struct timespec t_start; struct timespec t_end; uint64_t t; int error = 0; io_result_t io_res; clock_gettime(CLOCK_MONOTONIC, &t_start); ret = disk_dev_read(&disk->dev, offset, data_size, data, &io_res); clock_gettime(CLOCK_MONOTONIC, &t_end); t = (t_end.tv_sec - t_start.tv_sec) * 1000000000 + t_end.tv_nsec - t_start.tv_nsec; const uint64_t t_msec = t / 1000000; // Perform logging data_log_raw(&disk->data_raw, offset/disk->sector_size, data_size/disk->sector_size, &io_res, t); data_log(&disk->data_log, offset/disk->sector_size, data_size/disk->sector_size, &io_res, t); // Handle error or incomplete data if (io_res.data != DATA_FULL || io_res.error != ERROR_NONE) { int s_errno = errno; ERROR("Error when reading at offset %" PRIu64 " size %d read %zd, errno=%d: %s", offset, data_size, ret, errno, strerror(errno)); ERROR("Details: error=%s data=%s %02X/%02X/%02X", error_to_str(io_res.error), data_to_str(io_res.data), io_res.info.sense_key, io_res.info.asc, io_res.info.ascq); report_scan_error(disk, offset, data_size, t); disk->num_errors++; error = 1; if (io_res.error == ERROR_FATAL) { ERROR("Fatal error occurred, bailing out."); return false; } if (io_res.error == ERROR_UNKNOWN || (s_errno != EIO && s_errno != 0)) { if (state->num_unknown_errors++ > 500) { ERROR("%u unknown errors occurred, assuming fatal issue.", state->num_unknown_errors); return false; } ERROR("Unknown error occurred, possibly untranslated error by storage layers, trying to continue."); } } else { state->num_unknown_errors = 0; // Clear non-consecutive unknown errors report_scan_success(disk, offset, data_size, t); } hdr_record_value(disk->histogram, t / 1000); latency_bucket_add(disk, t_msec, state); if (t_msec > 1000) { VERBOSE("Scanning at offset %" PRIu64 " took %"PRIu64" msec", offset, t_msec); } if (disk->fix && (t_msec > 3000 || error)) { if (io_res.error != ERROR_UNCORRECTED) { INFO("Fixing region by rewriting, offset=%"PRIu64" size=%d", offset, data_size); ret = disk_dev_write(&disk->dev, offset, data_size, data, &io_res); if (ret != data_size) { ERROR("Error while attempting to rewrite the data! ret=%zd errno=%d: %s", ret, errno, strerror(errno)); } } else { // When we correct uncorrectable errors we want to zero it out, this should reduce any confusion later on when the data is read unsigned fix_offset = 0; int fix_size = 4096; if (data_size < fix_size) fix_size = data_size; for (; data_size >= (int)(fix_offset + fix_size); fix_offset += fix_size) { disk_dev_read(&disk->dev, offset+fix_offset, fix_size, data, &io_res); if (io_res.error == ERROR_UNCORRECTED) { INFO("Fixing uncorrectable region by writing zeros, offset=%"PRIu64" size=%d", offset+fix_offset, fix_size); memset(data, 0, fix_size); ret = disk_dev_write(&disk->dev, offset+fix_offset, fix_size, data, &io_res); if (ret != data_size) { ERROR("Error while attempting to overwrite uncorrectable data! ret=%zd errno=%d: %s", ret, errno, strerror(errno)); } } } } } return true; } static uint64_t calc_latency_stride(disk_t *disk) { const uint64_t num_sectors = disk->num_bytes / disk->sector_size; const uint64_t stride_size = num_sectors / disk->latency_graph_len; // At this stage stride_size may have a reminder, we need to distribute the // latencies a bit more to avoid it Since the remainder can never be more // than the latency_graph_len we can just add one entry to all the buckets return stride_size + 1; } static uint32_t *calc_scan_order_seq(disk_t *disk, uint64_t stride_size, int read_size_sectors) { uint64_t num_reads = stride_size / read_size_sectors + 2; uint32_t *order = malloc(sizeof(uint32_t) * num_reads); uint64_t i; for (i = 0; i < num_reads-1; i++) order[i] = i * read_size_sectors * disk->sector_size; order[i] = UINT32_MAX; return order; } static uint32_t *calc_scan_order_random(disk_t *disk, uint64_t stride_size, int read_size_sectors) { uint64_t num_reads = stride_size / read_size_sectors + 2; uint32_t *order = malloc(sizeof(uint32_t) * num_reads); // Fill sequential data uint64_t i; for (i = 0; i < num_reads - 1; i++) order[i] = i * read_size_sectors * disk->sector_size; order[i] = UINT32_MAX; // Shuffle it srand(time(NULL)); for (i = 0; i < num_reads - 1; i++) { uint64_t j = rand() % num_reads; if (i == j) continue; uint32_t tmp = order[i]; order[i] = order[j]; order[j] = tmp; } return order; } static uint32_t *calc_scan_order(disk_t *disk, enum scan_mode mode, uint64_t stride_size, int read_size) { int read_size_sectors = read_size / disk->sector_size; if (mode == SCAN_MODE_SEQ) return calc_scan_order_seq(disk, stride_size, read_size_sectors); else if (mode == SCAN_MODE_RANDOM) return calc_scan_order_random(disk, stride_size, read_size_sectors); else return NULL; } static void progress_calc(disk_t *disk, struct scan_state *state, uint64_t add) { bool do_update; if (add != 0) { state->progress_bytes += add; int progress_part_new = state->progress_bytes * state->progress_full / disk->num_bytes; do_update = progress_part_new != state->progress_part; state->progress_part = progress_part_new; } else { do_update = true; } if (do_update) { report_progress(disk, state->progress_part, state->progress_full); } } static bool disk_scan_latency_stride(disk_t *disk, struct scan_state *state, uint64_t base_offset, uint64_t data_size, uint32_t *scan_order) { unsigned i; uint64_t stride_end = base_offset + state->latency_stride * disk->sector_size; if (stride_end > disk->num_bytes) stride_end = disk->num_bytes; for (i = 0; disk->run && scan_order[i] != UINT32_MAX; i++) { uint64_t offset = base_offset + scan_order[i]; progress_calc(disk, state, data_size); VVVERBOSE("Scanning at offset %"PRIu64" index %u", offset, i); int64_t remainder = stride_end - offset; if (remainder < (int64_t)data_size) { data_size = remainder; VERBOSE("Last part scanning size %"PRIu64, data_size); } if (offset > disk->num_bytes || (offset+remainder) > disk->num_bytes) continue; if (!disk_scan_part(disk, offset, state->data, data_size, state)) return false; } return true; } static void set_realtime(bool realtime) { struct sched_param param; memset(¶m, 0, sizeof(param)); param.sched_priority = 1; if (realtime) sched_setscheduler(0, SCHED_RR, ¶m); else sched_setscheduler(0, SCHED_OTHER, ¶m); } static enum conclusion conclusion_calc(disk_t *disk) { if (disk->num_errors > 0) return CONCLUSION_FAILED_IO_ERRORS; if (hdr_max(disk->histogram) > 10000000) return CONCLUSION_FAILED_MAX_LATENCY; if (hdr_value_at_percentile(disk->histogram, 99.99) > 8000000) return CONCLUSION_FAILED_LATENCY_PERCENTILE; VERBOSE("Disk has passed the test"); return CONCLUSION_PASSED; } int disk_scan(disk_t *disk, enum scan_mode mode, unsigned data_size) { disk->run = 1; void *data = allocate_buffer(data_size); uint32_t *scan_order = NULL; int result = 0; struct scan_state state = {.latency = NULL, .progress_bytes = 0, .progress_full = 1000}; struct timespec ts_start; struct timespec ts_end; time_t scan_time; disk->conclusion = CONCLUSION_SCAN_PROBLEM; if (data_size % disk->sector_size != 0) { data_size -= data_size % disk->sector_size; if (data_size == 0) data_size = disk->sector_size; ERROR("Cannot scan data not in multiples of the sector size, adjusted scan size to %u", data_size); } set_realtime(true); clock_gettime(CLOCK_MONOTONIC, &ts_start); INFO("Scanning disk %s in %u byte steps", disk->path, data_size); scan_time = time(NULL); INFO("Scan started at: %s", ctime(&scan_time)); VVVERBOSE("Using buffer of size %d", data_size); if (data == NULL) { ERROR("Failed to allocate data buffer, errno=%d: %s", errno, strerror(errno)); result = 1; goto Exit; } uint64_t offset; const uint64_t disk_size_bytes = disk->num_bytes; const uint64_t latency_stride = calc_latency_stride(disk); VVERBOSE("latency stride is %"PRIu64, latency_stride); state.latency_bucket = 0; state.latency_stride = latency_stride; state.latency_count = 0; state.latency = malloc(sizeof(uint32_t) * latency_stride); state.data = data; scan_order = calc_scan_order(disk, mode, latency_stride, data_size); if (!scan_order) { result = 1; ERROR("Failed to generate scan order"); goto Exit; } verbose_extra_newline = 1; for (offset = 0; disk->run && offset < disk_size_bytes; offset += latency_stride * disk->sector_size) { VERBOSE("Scanning stride starting at %"PRIu64" done %"PRIu64"%%", offset, offset*100/disk_size_bytes); progress_calc(disk, &state, 0); latency_bucket_prepare(disk, &state, offset); if (!disk_scan_latency_stride(disk, &state, offset, data_size, scan_order)) break; latency_bucket_finish(disk, &state, offset + latency_stride * disk->sector_size); if (disk->is_ata) disk_ata_monitor(disk); else disk_scsi_monitor(disk); } verbose_extra_newline = 0; if (!disk->run) { INFO("Disk scan interrupted"); disk->conclusion = CONCLUSION_ABORTED; } else { disk->conclusion = conclusion_calc(disk); } report_scan_done(disk); Exit: clock_gettime(CLOCK_MONOTONIC, &ts_end); set_realtime(false); free(scan_order); free_buffer(data, data_size); free(state.latency); disk->run = 0; scan_time = time(NULL); INFO("Scan ended at: %s", ctime(&scan_time)); INFO("Scan took %d second", (int)(ts_end.tv_sec - ts_start.tv_sec)); return result; } diskscan-0.21/lib/sha1.c000066400000000000000000000266251456470715000150250ustar00rootroot00000000000000/* 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 07/2002 By Ralph Giles Still 100% public domain modified for use with stdint types, autoconf code cleanup, removed attribution comments switched SHA1Final() argument order for consistency use SHA1_ prefix for public api move public api to sha1.h */ /* 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 */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #include #include #include #include "sha1.h" void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]); #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 */ /* FIXME: can we do this in an endian-proof way? */ #ifdef WORDS_BIGENDIAN #define blk0(i) block->l[i] #else #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ |(rol(block->l[i],8)&0x00FF00FF)) #endif #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 /* VERBOSE */ /* Hash a single 512-bit block. This is the core of the algorithm. */ void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) { uint32_t a, b, c, d, e; typedef union { uint8_t c[64]; uint32_t l[16]; } CHAR64LONG16; CHAR64LONG16* block; #ifdef SHA1HANDSOFF static uint8_t 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 SHA1_Init(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 SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len) { size_t i, j; #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)); SHA1_Transform(context->state, context->buffer); for ( ; i + 63 < len; i += 64) { SHA1_Transform(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 SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]) { uint32_t i; uint8_t 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 */ } SHA1_Update(context, (uint8_t *)"\200", 1); while ((context->count[0] & 504) != 448) { SHA1_Update(context, (uint8_t *)"\0", 1); } SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ for (i = 0; i < SHA1_DIGEST_SIZE; i++) { digest[i] = (uint8_t) ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); } /* Wipe variables */ i = 0; 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 its own static vars */ SHA1_Transform(context->state, context->buffer); #endif } /*************************************************************/ #if 0 int main(int argc, char** argv) { int i, j; SHA1_CTX context; unsigned char digest[SHA1_DIGEST_SIZE], buffer[16384]; FILE* file; if (argc > 2) { puts("Public domain SHA-1 implementation - by Steve Reid "); puts("Modified for 16 bit environments 7/98 - by James H. Brown "); /* JHB */ puts("Produces the SHA-1 hash of a file, or stdin if no file is specified."); return(0); } if (argc < 2) { file = stdin; } else { if (!(file = fopen(argv[1], "rb"))) { fputs("Unable to open file.", stderr); return(-1); } } SHA1_Init(&context); while (!feof(file)) { /* note: what if ferror(file) */ i = fread(buffer, 1, 16384, file); SHA1_Update(&context, buffer, i); } SHA1_Final(&context, digest); fclose(file); for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) { for (j = 0; j < 4; j++) { printf("%02X", digest[i*4+j]); } putchar(' '); } putchar('\n'); return(0); /* JHB */ } #endif /* self test */ #ifdef TEST static char *test_data[] = { "abc", "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", "A million repetitions of 'a'"}; static char *test_results[] = { "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D", "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1", "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"}; void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output) { int i,j; char *c = output; for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) { for (j = 0; j < 4; j++) { sprintf(c,"%02X", digest[i*4+j]); c += 2; } sprintf(c, " "); c += 1; } *(c - 1) = '\0'; } int main(int argc, char** argv) { int k; SHA1_CTX context; uint8_t digest[20]; char output[80]; fprintf(stdout, "verifying SHA-1 implementation... "); for (k = 0; k < 2; k++){ SHA1_Init(&context); SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k])); SHA1_Final(&context, digest); digest_to_hex(digest, output); if (strcmp(output, test_results[k])) { fprintf(stdout, "FAIL\n"); fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]); fprintf(stderr,"\t%s returned\n", output); fprintf(stderr,"\t%s is correct\n", test_results[k]); return (1); } } /* million 'a' vector we feed separately */ SHA1_Init(&context); for (k = 0; k < 1000000; k++) SHA1_Update(&context, (uint8_t*)"a", 1); SHA1_Final(&context, digest); digest_to_hex(digest, output); if (strcmp(output, test_results[2])) { fprintf(stdout, "FAIL\n"); fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]); fprintf(stderr,"\t%s returned\n", output); fprintf(stderr,"\t%s is correct\n", test_results[2]); return (1); } /* success */ fprintf(stdout, "ok\n"); return(0); } #endif /* TEST */ diskscan-0.21/lib/sha1.h000066400000000000000000000011151456470715000150150ustar00rootroot00000000000000/* public api for steve reid's public domain SHA-1 implementation */ /* this file is in the public domain */ #ifndef __SHA1_H #define __SHA1_H #ifdef __cplusplus extern "C" { #endif #include #include typedef struct { uint32_t state[5]; uint32_t count[2]; uint8_t buffer[64]; } SHA1_CTX; #define SHA1_DIGEST_SIZE 20 void SHA1_Init(SHA1_CTX* context); void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len); void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE]); #ifdef __cplusplus } #endif #endif /* __SHA1_H */ diskscan-0.21/lib/system_id.c000066400000000000000000000041271456470715000161620ustar00rootroot00000000000000#include "system_id.h" #include "sha1.h" #include "arch.h" #include #include #include #include #include #include static void sha1_calc(const unsigned char *src, int src_len, char *out, int out_size) { assert(out_size >= SHA1_DIGEST_SIZE*2+1); unsigned char digest[SHA1_DIGEST_SIZE]; SHA1_CTX sha1_ctx; SHA1_Init(&sha1_ctx); SHA1_Update(&sha1_ctx, src, src_len); SHA1_Final(&sha1_ctx, digest); int i; for (i = 0; i < SHA1_DIGEST_SIZE; i++) { sprintf(out + i*2, "%02X", digest[i]); } } static bool cmd_str(const char *cmd, char *buf, int len) { FILE *f = popen(cmd, "r"); if (!f) return false; char *ret = fgets(buf, len, f); pclose(f); return ret != NULL; } static void dmidecode_read(const char *field_name, char *buf, int len) { char cmd[128]; memset(buf, 0, len); snprintf(cmd, sizeof(cmd), "dmidecode -s %s", field_name); if (!cmd_str(cmd, buf, len)) return; int actual_len = strlen(buf); switch (buf[actual_len-1]) { case '\r': case '\n': buf[actual_len-1] = 0; actual_len--; break; } sha1_calc((unsigned char *)buf, actual_len, buf, len); } static void system_serial_read(char *buf, int len) { dmidecode_read("system-serial-number", buf, len); } static void chassis_serial_read(char *buf, int len) { dmidecode_read("chassis-serial-number", buf, len); } static void baseboard_serial_read(char *buf, int len) { dmidecode_read("baseboard-serial-number", buf, len); } static void os_read(char *buf, int len) { cmd_str("uname -o", buf, len); int i; for (i = strlen(buf) - 1; i >= 0; i--) { if (!isspace(buf[i])) break; buf[i] = 0; } } bool system_identifier_read(system_identifier_t *system_id) { os_read(system_id->os, sizeof(system_id->os)); system_serial_read(system_id->system, sizeof(system_id->system)); chassis_serial_read(system_id->chassis, sizeof(system_id->chassis)); baseboard_serial_read(system_id->baseboard, sizeof(system_id->baseboard)); unsigned char mac[6]; mac_read(mac, sizeof(mac)); sha1_calc(mac, sizeof(mac), system_id->mac, sizeof(system_id->mac)); return true; } diskscan-0.21/lib/system_id.h000066400000000000000000000004301456470715000161600ustar00rootroot00000000000000#ifndef SYSTEM_ID_H #define SYSTEM_ID_H #include typedef struct system_identifier_t { char os[64]; char system[64]; char chassis[64]; char baseboard[64]; char mac[64]; } system_identifier_t; bool system_identifier_read(system_identifier_t *system_id); #endif diskscan-0.21/lib/verbose.c000066400000000000000000000014171456470715000156260ustar00rootroot00000000000000/* * Copyright 2013 Baruch Even * * This file is part of DiskScan. * * DiskScan is free software: 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 3 of the License, or * (at your option) any later version. * * DiskScan is distributed in the hope that 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 DiskScan. If not, see . * */ #include "verbose.h" int verbose; diskscan-0.21/libscsicmd/000077500000000000000000000000001456470715000153605ustar00rootroot00000000000000diskscan-0.21/libscsicmd/.gitignore000066400000000000000000000005611456470715000173520ustar00rootroot00000000000000*.o .*.d .gdb_history tags libscsicmd.a ata_identify ata_identify_dump.[ch] ata_smart_return_status ata_smart_read_data ata_check_power_mode sense_decode scsi_read_capacity_10 scsi_read_capacity_16 scsi_inquiry scsi_log_sense scsi_mode_sense scsi_receive_diagnostics parse_scsi collect_raw_data test/libtestlib.a CMakeCache.txt CMakeFiles Makefile cmake_install.cmake diskscan-0.21/libscsicmd/CMakeLists.txt000066400000000000000000000006441456470715000201240ustar00rootroot00000000000000cmake_minimum_required(VERSION 2.8) project(libscsicmd) export(PACKAGE libscsicmd) include_directories("include") add_compile_options(-Wall -Wextra -Wshadow -Wmissing-prototypes -Winit-self -g) add_definitions(-D_GNU_SOURCE -D_FORTIFY_SOURCE=2) set(CMAKE_C_FLAGS_DEBUG "-Werror -O0 ${CMAKE_C_FLAGS_DEBUG}") set(CMAKE_C_FLAGS_RELEASE "-Wall -O3 ${CMAKE_C_FLAGS_RELEASE}") add_subdirectory(src) add_subdirectory(test) diskscan-0.21/libscsicmd/LICENSE000066400000000000000000000261351456470715000163740ustar00rootroot00000000000000 Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "[]" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. diskscan-0.21/libscsicmd/README.md000066400000000000000000000017751456470715000166510ustar00rootroot00000000000000# libscsicmd A library to create SCSI commands (CDBs) and parse the results, also for ATA commands and results. This library doesn't deal with actually submitting the CDBs or getting the results from the storage device, only with the commands themselves. The actual sending of the command is different between the different OSes and this library tries to be OS agnostic. ## Build The build system is using cmake, you need to get it before you can build. To build, run: cmake . && make For a developer debug build use: cmake -DCMAKE_BUILD_TYPE=Debug . To build for American Fuzzy Lop instrumentation: cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER=/usr/bin/afl-gcc -DCMAKE_C_FLAGS=-DAFL_HARDEN=1 . ## Testing Testing is either done manually with some raw data collected from SCSI devices with test/collect\_raw\_data or with American Fuzzy Lop (AFL) for parsing problems. Using AFL: afl-fuzz -t 200 -i afl/testcase -o afl/finding test/parse_scsi ## Author Baruch Even diskscan-0.21/libscsicmd/afl/000077500000000000000000000000001456470715000161225ustar00rootroot00000000000000diskscan-0.21/libscsicmd/afl/testcase/000077500000000000000000000000001456470715000177355ustar00rootroot00000000000000diskscan-0.21/libscsicmd/afl/testcase/186704e9f39832c4c7b4f2ab71c52762017bd728000066400000000000000000000142141456470715000250320ustar00rootroot00000000000000,4d 00 55 00 00 00 00 40 00 00,,95 00 08 20 00 00 03 0c 00 10 9a 5e 00 08 02 32 00 00 02 32 00 01 03 14 00 00 16 c7 51 17 01 20 3b 37 06 46 00 00 00 00 0a 3b 31 ae 00 02 03 14 00 00 1e bc 51 17 01 20 45 0e 05 59 00 00 00 00 0b ef ff f5 00 03 03 14 00 00 29 a5 51 17 01 20 30 f7 01 4a 00 00 00 00 08 7d ea bc 00 04 03 14 00 00 31 95 51 17 01 20 30 f7 01 4e 00 00 00 00 08 7d ea c0 00 05 03 14 00 00 59 54 51 17 01 20 45 39 00 b7 00 00 00 00 0b f1 22 f3 00 06 03 14 00 02 10 4d 51 17 01 20 00 e1 01 a7 00 00 00 00 00 3c e8 11 00 07 03 14 00 02 8b 87 51 17 01 20 1d d9 07 13 00 00 00 00 05 4e 51 89 00 08 03 14 00 02 ad a8 51 17 01 20 55 1a 06 06 00 00 00 00 0e ad 67 8d 00 09 03 14 00 03 4a 6b 51 17 01 20 99 22 05 2c 00 00 00 00 19 c7 58 b0 00 0a 03 14 00 03 68 e6 51 17 01 20 88 b8 02 de 00 00 00 00 17 26 3a 94 00 0b 03 14 00 03 69 5f 51 17 01 40 17 58 04 d2 00 00 00 00 04 2f dc f6 00 0c 03 14 00 03 ac 6d 51 17 01 20 15 b2 02 54 00 00 00 00 03 d7 af b1 00 0d 03 14 00 03 de b4 51 17 01 20 00 e1 01 a3 00 00 00 00 00 3c e8 0d 00 0e 03 14 00 03 de b7 51 17 01 20 10 47 02 79 00 00 00 00 02 d9 5c d5 00 0f 03 14 00 03 de d5 51 17 01 20 ab a0 02 c8 00 00 00 00 1c c6 eb 8a 00 10 03 14 00 05 a8 fc 51 17 01 20 15 b2 02 51 00 00 00 00 03 d7 af ae 00 11 03 14 00 06 26 4e 51 17 01 20 15 b2 02 43 00 00 00 00 03 d7 af a0 00 12 03 14 00 06 33 f7 51 17 01 20 29 da 06 1f 00 00 00 00 07 53 23 4b 00 13 03 14 00 06 34 b2 51 17 01 20 17 38 01 ee 00 00 00 00 04 21 d7 6e 00 14 03 14 00 06 35 bc 51 17 01 20 01 d5 03 8f 00 00 00 00 00 57 bd 11 00 15 03 14 00 06 35 c5 51 17 01 20 1c 58 04 53 00 00 00 00 05 04 4a 6e 00 16 03 14 00 06 35 d0 51 17 01 20 3a c6 03 6b 00 00 00 00 0a 38 17 d3 00 17 03 14 00 06 36 cb 51 17 01 20 01 d5 03 8e 00 00 00 00 00 57 bd 10 00 18 03 14 00 06 3c ba 51 17 01 20 49 43 05 2e 00 00 00 00 0c ae da 39 00 19 03 14 00 06 6e 21 51 17 01 20 1d f8 02 78 00 00 00 00 05 4f 2a c6 00 1a 03 14 00 06 96 52 51 17 01 20 9d 87 04 b7 00 00 00 00 1a 71 05 cf 00 1b 03 14 00 06 97 30 51 17 01 20 2a a3 02 72 00 00 00 00 07 81 d5 26 00 1c 03 14 00 06 cb 8a 51 17 01 20 3e 2d 01 d2 00 00 00 00 0a cc 67 e2 00 1d 03 14 00 07 22 0b 51 17 01 20 1c 07 06 77 00 00 00 00 04 e4 bf 7b 00 1e 03 14 00 07 40 c7 51 17 01 20 86 3c 05 8d 00 00 00 00 16 c5 84 e5 00 1f 03 14 00 07 9d ea 51 17 01 20 19 70 02 06 00 00 00 00 04 70 f9 79 00 20 03 14 00 08 21 6f 51 17 01 20 01 8e 07 1f 00 00 00 00 00 39 4f e2 00 21 03 14 00 08 26 28 51 17 01 20 00 72 00 2c 00 00 00 00 00 0f c6 34 00 22 03 14 00 08 26 29 51 17 01 20 01 8e 07 12 00 00 00 00 00 39 4f d5 00 23 03 14 00 08 26 29 51 17 01 20 01 8e 07 13 00 00 00 00 00 39 4f d6 00 24 03 14 00 08 27 8c 51 17 01 20 00 72 00 27 00 00 00 00 00 0f c6 2f 00 25 03 14 00 08 3c d8 51 17 01 20 00 72 00 28 00 00 00 00 00 0f c6 30 00 26 03 14 00 08 3c ef 51 17 01 20 49 55 03 96 00 00 00 00 0c ae 5c e1 00 27 03 14 00 08 e6 f0 51 17 01 20 00 72 00 30 00 00 00 00 00 0f c6 38 00 28 03 14 00 09 9f eb 51 17 01 20 1c ce 02 64 00 00 00 00 05 07 94 ef 00 29 03 14 00 0a 4b aa 51 17 01 20 31 d6 06 4f 00 00 00 00 08 a7 65 49 00 2a 03 14 00 0a 4b af 51 17 01 20 3f 3d 00 16 00 00 00 00 0a f9 70 ad 00 2b 03 14 00 0b 70 fb 51 17 01 20 e9 d6 04 fc 00 00 00 00 26 72 2e ad 00 2c 03 14 00 0b 7d 35 51 17 01 20 3f 49 05 ee 00 00 00 00 0a f9 22 85 00 2d 03 14 00 0b 89 09 51 17 01 20 3c 2d 03 dd 00 00 00 00 0a 62 eb cd 00 2e 03 14 00 0b 8c 1f 51 17 01 20 00 ea 02 ce 00 00 00 00 00 3c a8 e7 00 2f 03 14 00 0b 94 3b 51 17 01 20 1d 18 04 a1 00 00 00 00 05 34 11 af 00 30 03 14 00 0b 9e fd 51 17 01 20 1e 6f 02 cf 00 00 00 00 05 52 7e b5 00 31 03 14 00 0b 9f 0a 51 17 01 20 44 26 02 43 00 00 00 00 0b d3 cd c3 00 32 03 14 00 0b a2 ce 51 17 01 20 01 69 05 7e 00 00 00 00 00 3a 55 bb 00 33 03 14 00 0b a7 5a 51 17 01 20 24 e8 00 97 00 00 00 00 06 77 04 e1 00 34 03 14 00 0b a8 b0 51 17 01 20 24 e8 00 9a 00 00 00 00 06 77 04 e4 00 35 03 14 00 0b f1 4c 51 17 01 21 2e 62 05 23 00 00 00 00 30 be 48 20 00 36 03 14 00 0c 09 56 51 17 01 20 35 88 01 66 00 00 00 00 09 58 a2 d3 00 37 03 14 00 0c 21 c0 51 17 01 21 2e 62 05 25 00 00 00 00 30 be 48 22 00 38 03 14 00 0c 2d f8 51 17 01 20 24 e8 00 ae 00 00 00 00 06 77 04 f8 00 39 03 14 00 0c 36 fe 51 17 01 20 9e 49 05 6c 00 00 00 00 1a 97 f7 b3 00 3a 03 14 00 0c 4d ef 51 17 01 20 24 e8 00 a9 00 00 00 00 06 77 04 f3 00 3b 03 14 00 0c 4f 52 51 17 01 20 4f 03 02 9e 00 00 00 00 0d a4 fe 0e 00 3c 03 14 00 0c 5b 5b 51 17 01 20 24 e8 00 9b 00 00 00 00 06 77 04 e5 00 3d 03 14 00 0c 81 ec 51 17 01 20 24 e8 00 aa 00 00 00 00 06 77 04 f4 00 3e 03 14 00 0c 81 ec 51 17 01 20 24 e8 00 ab 00 00 00 00 06 77 04 f5 00 3f 03 14 00 0c 88 98 51 17 01 21 2e 62 05 26 00 00 00 00 30 be 48 23 00 40 03 14 00 0c ab 23 51 17 01 20 00 03 02 0a 00 00 00 00 00 0c ae 1a 00 41 03 14 00 0c d8 7f 51 17 01 20 9e 49 05 70 00 00 00 00 1a 97 f7 b7 00 42 03 14 00 0c e0 ab 51 17 01 20 ed 32 00 6a 00 00 00 00 26 f5 c6 52 00 43 03 14 00 0c ef 0e 51 17 01 20 68 a7 03 a1 00 00 00 00 11 e1 48 c4 00 44 03 14 00 0d 00 1c 51 17 01 20 1e 6f 02 ce 00 00 00 00 05 52 7e b4 00 45 03 14 00 0d 06 3b 51 17 01 20 93 c6 06 5f 00 00 00 00 18 fa 98 dd 00 46 03 14 00 0d 0b ff 51 17 01 20 24 e8 00 99 00 00 00 00 06 77 04 e3 00 47 03 14 00 0d 6b 5f 51 17 01 20 05 9e 04 3a 00 00 00 00 00 f1 53 b6 00 48 03 14 00 0d 7b 58 51 17 01 20 24 e8 00 8f 00 00 00 00 06 77 04 d9 00 49 03 14 00 0d 86 9c 51 17 01 21 2e 62 05 27 00 00 00 00 30 be 48 24 00 4a 03 14 00 0d da 5b 51 17 01 20 29 b2 00 d2 00 00 00 00 07 52 05 fe 00 4b 03 14 00 0d da 81 51 17 01 20 9e 49 05 74 00 00 00 00 1a 97 f7 bb 00 4c 03 14 00 0e 1f 48 51 17 01 40 2d e3 06 44 00 00 00 00 08 09 eb 8e 00 4d 03 14 00 0e 4b 21 51 17 01 20 4f 03 02 9a 00 00 00 00 0d a4 fe 0a 00 4e 03 14 00 0e 5e 54 51 17 01 20 24 e8 00 9f 00 00 00 00 06 77 04 e9 00 4f 03 14 00 0e 71 d2 51 17 01 20 24 e8 00 9e 00 00 00 00 06 77 04 e8 00 50 03 14 00 0e 99 b1 51 17 01 20 29 b2 00 ce 00 00 00 00 07 52 05 fa 00 51 03 14 00 0f 10 6f 51 17 01 20 05 9e 04 3b 00 00 00 00 00 f1 53 b7 00 52 03 14 00 0f 13 48 51 17 01 21 87 1b 01 8e 00 00 00 00 3d 55 25 d6 00 53 03 14 00 0f 29 da 51 17 01 20 7f 65 00 1d 00 00 00 00 15 ac 02 e4 00 54 03 14 00 0f 71 11 51 17 01 20 1d 18 04 a0 00 00 00 00 05 34 11 ae 00 55 03 14 00 0f c7 1a 51 17 01 20 c2 04 05 15 00 00 00 00 20 3f 7a 16 00 56 03 14 00 0f ce ab 51 17 01 20 29 b2 00 d1 00 00 00 00 07 52 05 fd diskscan-0.21/libscsicmd/afl/testcase/1b5fac8682806d6e823c301159d6da81e30f421a000066400000000000000000000001771456470715000251540ustar00rootroot00000000000000,4d 00 40 03 00 00 00 40 00 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 03 00 00 f8 23 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/28eeac63bfcf7ad2126d2eddcdc04019270075ec000066400000000000000000000016141456470715000256020ustar00rootroot00000000000000,1c 01 05 40 00 00,,05 00 01 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 46 41 14 0f 76 73 14 0f 76 73 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 55 52 14 0f 55 52 14 0f 76 73 14 0f 76 73 14 0f 00 00 00 00 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 0e 0a 0a 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/2b34251f3421af9a5c53a41f7e27f1cc3e8a13b0000066400000000000000000000003241456470715000252670ustar00rootroot00000000000000,5a 00 3f ff 00 00 00 10 00 00,,00 3a 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 27 10 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 00 00 18 06 06 00 00 00 00 00 19 0e 46 00 07 d0 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/39c99f32ec43d6ee12857a64e031114ae7cf23cd.csv000066400000000000000000000000411456470715000261060ustar00rootroot00000000000000,25 00 00 00 00 00 00 00 00 00,, diskscan-0.21/libscsicmd/afl/testcase/4941885df82498d8ca26375728606d41be818e27000066400000000000000000000004201456470715000247160ustar00rootroot00000000000000,4d 00 40 ff 00 00 00 40 00 00,,00 00 00 4c 00 00 00 ff 02 00 02 ff 03 00 03 ff 05 00 05 ff 06 00 06 ff 0c 00 0c ff 0d 00 0d ff 0e 00 0e ff 0f 00 0f ff 10 00 10 ff 11 00 11 ff 15 00 15 ff 18 00 18 ff 19 00 19 ff 1a 00 1a ff 2f 00 2f ff 30 00 30 ff 31 00 31 ff 38 00 38 ff diskscan-0.21/libscsicmd/afl/testcase/554ff10f0a6f35849db7e44176aa94c6dc232872.csv000066400000000000000000000000631456470715000257620ustar00rootroot00000000000000,9e 10 00 00 00 00 00 00 00 00 00 00 02 00 00 00,, diskscan-0.21/libscsicmd/afl/testcase/5b7d04cbfbe29ec8f91526131c87e7cc8e9ea10e000066400000000000000000000003701456470715000255520ustar00rootroot00000000000000,4d 00 40 ff 00 00 00 40 00 00,,40 ff 00 44 00 00 00 ff 02 00 02 ff 03 00 03 ff 05 00 05 ff 06 00 06 ff 0d 00 0d ff 0e 00 0e ff 0f 00 0f ff 10 00 10 ff 11 00 11 ff 15 00 15 ff 18 00 18 ff 1a 00 1a ff 2f 00 2f ff 30 00 30 ff 31 00 31 ff 37 00 37 ff diskscan-0.21/libscsicmd/afl/testcase/617ce3a43c7dbb1ba99a422ce455c1b55d2260b4.csv000066400000000000000000000000761456470715000261500ustar00rootroot00000000000000,1c 01 00 40 00 00,,00 00 00 0a 00 01 02 04 05 07 0d 0e 0f 1d diskscan-0.21/libscsicmd/afl/testcase/6184436113637747407bf86315ebd987300b8799000066400000000000000000000000541456470715000244700ustar00rootroot00000000000000,37 00 0a 00 00 00 00 02 00 00,,00 0a 00 00 diskscan-0.21/libscsicmd/afl/testcase/657af263aa78ee4d6b755df9e00a159d5c88dc2a.csv000066400000000000000000000000461456470715000262670ustar00rootroot00000000000000,1c 01 00 40 00 00,,00 00 00 02 00 3f diskscan-0.21/libscsicmd/afl/testcase/745f69394ad87d7d234e796b1a54a31f970e2510.csv000066400000000000000000000014211456470715000256300ustar00rootroot00000000000000,1a 00 3f ff ff 00,,37 00 00 08 00 00 00 00 00 00 02 00 01 0a 80 00 00 00 00 00 00 00 00 00 08 12 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0a 0a 02 00 00 00 00 00 ff ff 00 1e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/7c597125d72d146425d1899f6512b82df99b59c1000066400000000000000000000030151456470715000247730ustar00rootroot00000000000000,b7 14 00 00 00 00 00 00 02 00 00 00,,00 16 00 00 00 00 17 f8 00 00 00 72 00 00 00 33 00 00 00 0f 00 00 00 70 00 00 00 17 00 00 00 cc 00 00 00 17 00 00 00 d0 00 00 00 61 00 00 01 85 00 00 00 0f 00 00 02 00 00 00 00 00 00 00 02 02 00 00 00 00 00 00 02 03 00 00 00 01 00 00 02 02 00 00 00 01 00 00 02 03 00 00 00 02 00 00 02 02 00 00 00 02 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 0 diskscan-0.21/libscsicmd/afl/testcase/7e1e393db35bd119ab38a395829ff5deadd9501a000066400000000000000000000000541456470715000254640ustar00rootroot00000000000000,1c 01 1b 40 00 00,,1b 00 00 04 00 01 00 03 diskscan-0.21/libscsicmd/afl/testcase/7eeaad7ca0a2197d1283c87d441a15f6c8d5e6f6000066400000000000000000000002001456470715000254540ustar00rootroot00000000000000,25 00 00 00 00 00 00 00 00 00,70 00 04 00 00 00 00 18 00 00 00 00 29 07 00 00 00 00 00 00 f5 19 00 00 00 00 00 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/801bc5987bfe420b04e07eb1cd5ae0462a0b750c000066400000000000000000000001631456470715000253470ustar00rootroot00000000000000,37 00 0e 00 00 00 00 00 08 00,70 00 01 00 00 00 00 10 00 00 00 00 1c 00 00 80 00 00 00 21 1c 00 00 00,00 0c 00 00 diskscan-0.21/libscsicmd/afl/testcase/8329e3313860bfd6b8dd1252b4a4542d4c791f13.csv000066400000000000000000000030401456470715000256630ustar00rootroot00000000000000,37 00 08 00 00 00 00 00 08 00,,00 00 00 05 00 3f 45 46 82 27 21 60 00 00 02 00 81 0a c4 01 00 00 00 00 00 00 0c 00 82 0e 00 00 00 00 00 00 01 f4 00 00 00 00 00 00 03 16 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 40 00 00 00 04 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 04 01 00 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 8a 0a 00 10 00 00 00 00 00 00 00 06 ca 01 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ca 02 01 8c 00 00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 00 00 ff ff 00 00 00 00 00 00 00 00 ff ff ff ff ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/86f870fdeb8e99954869aaf1b58e456109e2e6c8000066400000000000000000000002131456470715000253120ustar00rootroot00000000000000,37 00 0a 00 00 00 00 00 08 00,70 00 01 00 00 00 00 18 00 00 00 00 1c 02 00 c0 00 02 00 00 17 48 00 00 00 00 00 00 00 00 00 00,00 0e 00 00 diskscan-0.21/libscsicmd/afl/testcase/90548a1ef4bae0b9b7382497097a01691333fb4f000066400000000000000000000065301456470715000251100ustar00rootroot00000000000000,1c 01 01 40 00 00,,01 04 04 68 00 00 00 08 11 00 0a ea 50 06 04 80 a0 1c 19 3e 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 4c 43 43 20 20 20 30 42 33 30 07 81 42 02 00 01 02 55 53 31 44 30 31 31 30 35 30 30 30 35 39 00 00 05 40 a6 20 31 35 31 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 20 20 33 31 34 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 21 20 32 32 32 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 22 20 32 31 36 20 53 58 50 20 33 36 78 36 47 73 65 63 00 40 23 20 30 32 31 20 43 44 45 46 00 00 00 00 00 00 00 00 00 10 02 80 00 01 03 00 02 01 04 80 02 00 05 01 40 00 06 03 40 00 07 85 00 00 08 86 00 00 09 02 00 00 0a 02 01 00 0b 02 02 00 0c 02 03 00 0d 02 04 00 0e 02 05 00 0f 02 06 00 10 02 07 00 11 04 00 00 02 c0 c1 05 4c 43 43 20 42 11 01 06 b5 50 06 04 80 d8 21 42 be 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 4c 43 43 20 20 20 30 42 33 30 07 80 41 02 01 00 01 4a 57 58 45 4c 31 33 30 35 30 30 35 35 31 00 00 05 5a 06 20 31 35 31 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 00 20 33 31 34 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 01 20 32 32 32 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 02 20 32 31 36 20 53 58 50 20 33 36 78 36 47 73 65 63 00 5a 03 20 30 32 31 20 43 44 45 46 00 00 00 00 00 00 00 00 00 03 12 00 03 01 13 80 03 00 14 03 5a 00 01 c2 05 4c 43 43 20 41 11 02 04 4f 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 44 65 72 72 69 6e 67 65 72 20 45 6e 63 6c 20 20 30 30 31 31 0e 1f 4d 02 02 02 00 43 4b 4d 30 30 31 33 31 38 30 31 37 35 38 00 00 00 02 00 00 01 01 01 80 01 00 01 c3 07 43 68 61 73 73 69 73 11 03 03 6a 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 30 30 30 42 30 30 31 39 00 00 00 00 00 00 00 00 32 41 31 30 02 81 42 02 00 04 33 41 43 37 42 30 31 33 30 32 31 37 38 31 39 20 20 01 86 a4 20 35 2e 33 33 53 58 50 33 36 78 36 47 00 00 00 00 00 02 15 00 04 01 16 80 04 00 01 c4 0e 50 6f 77 65 72 20 53 75 70 70 6c 79 20 42 11 04 03 56 50 06 04 80 00 00 00 00 45 4d 43 20 20 20 20 20 45 4d 43 20 44 45 52 52 49 4e 47 45 52 20 50 53 43 30 33 30 02 80 41 02 01 03 32 41 43 37 42 30 31 33 30 32 31 37 35 31 38 20 20 00 02 17 00 05 01 18 80 05 00 01 c5 0e 50 6f 77 65 72 20 53 75 70 70 6c 79 20 41 17 19 00 0c 04 01 00 0e 0e 01 00 05 81 25 00 0c 18 01 00 0a 07 01 00 0c 19 0a 00 0f 0c 02 00 0d 0c 01 00 0c 10 01 00 08 04 01 01 0e 0e 01 01 05 81 08 01 0c 18 01 01 0a 07 01 01 0c 19 0a 01 0f 0e 01 02 09 03 00 02 0d 04 01 02 0e 19 1a 02 0f 03 02 03 0d 04 02 03 0e 02 01 03 0e 03 02 04 0d 04 02 04 0e 02 01 04 0e 41 72 72 61 79 20 44 65 76 69 63 65 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 42 4c 43 43 20 42 45 78 70 61 6e 64 65 72 20 50 68 79 45 78 70 61 6e 64 65 72 20 42 43 6f 6e 74 72 6f 6c 6c 65 72 20 42 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 42 44 69 73 70 6c 61 79 20 47 72 65 65 6e 44 69 73 70 6c 61 79 20 42 6c 75 65 4c 61 6e 67 75 61 67 65 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 41 4c 43 43 20 41 45 78 70 61 6e 64 65 72 20 50 68 79 45 78 70 61 6e 64 65 72 20 41 43 6f 6e 74 72 6f 6c 6c 65 72 20 41 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 41 45 6e 63 6c 6f 73 75 72 65 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 4d 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 4d 53 41 53 20 43 6f 6e 6e 65 63 74 6f 72 20 4d 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 42 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 42 50 6f 77 65 72 20 53 75 70 70 6c 79 20 42 43 6f 6f 6c 69 6e 67 20 46 61 6e 20 41 54 65 6d 70 2e 20 53 65 6e 73 6f 72 20 41 50 6f 77 65 72 20 53 75 70 70 6c 79 20 41 diskscan-0.21/libscsicmd/afl/testcase/9062ca40d53bbf790d9338ed79b5215ca76178d2.csv000066400000000000000000000000511456470715000257560ustar00rootroot00000000000000,1c 01 00 40 00 00,,00 00 00 03 00 3f 82 diskscan-0.21/libscsicmd/afl/testcase/961ce3b94d711105a238b82068012e5b765b4027000066400000000000000000000001641456470715000246450ustar00rootroot00000000000000,1c 01 00 40 00 00,70 00 02 00 00 00 00 18 00 00 00 00 31 01 00 00 00 00 00 00 f5 07 00 00 00 00 00 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/9c3040be62f1785b6387524185ae7508966a8fca000066400000000000000000000001041456470715000250340ustar00rootroot00000000000000,4d 00 40 ff 00 00 00 40 00 00,,40 ff 00 04 00 ff 34 ff 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/9da9f3b23df2a728a486968d9e4f4a87aff34bf6.csv000066400000000000000000000001231456470715000263060ustar00rootroot00000000000000,1c 01 00 40 00 00,,00 00 00 11 00 01 02 04 05 0a 0e 10 11 80 81 82 83 90 91 f0 f1 diskscan-0.21/libscsicmd/afl/testcase/a051877bf52e199210ffd96778f7698e3dc6978e.csv000066400000000000000000000030161456470715000257530ustar00rootroot00000000000000,1c 01 04 40 00 00,,04 00 01 fa 30 37 3a 30 32 3a 31 31 3a 35 34 3a 35 33 37 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 34 38 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 72 65 61 64 79 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 35 31 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 6c 69 6e 6b 20 72 65 61 64 79 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 35 38 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 72 61 74 65 20 75 6e 6b 6e 6f 77 6e 2d 3e 36 47 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 36 32 20 64 65 76 2f 70 68 79 2e 32 32 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 66 66 2d 3e 30 78 30 30 0a 30 37 3a 30 32 3a 31 31 3a 35 34 3a 37 38 37 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 31 20 64 61 74 61 3a 20 30 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 61 34 0a 30 37 3a 30 32 3a 31 31 3a 35 36 3a 37 37 35 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 37 3a 30 32 3a 31 31 3a 35 36 3a 37 38 34 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a diskscan-0.21/libscsicmd/afl/testcase/a3a3b5b0ea540bc579228dfe70b21f40d9c0df96000066400000000000000000000200331456470715000254410ustar00rootroot00000000000000,1c 01 04 40 00 00,,04 00 0a a9 30 35 3a 31 37 3a 33 36 3a 35 38 3a 33 38 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 32 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 33 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 34 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 37 3a 30 31 3a 33 35 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 38 32 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 38 36 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 35 39 36 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 38 3a 35 38 3a 36 30 35 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 30 37 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 31 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 32 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 33 39 3a 30 31 3a 31 33 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 35 38 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 35 39 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 36 30 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 30 3a 35 38 3a 36 31 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 33 34 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 33 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 34 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 31 3a 30 31 3a 31 35 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 35 30 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 35 34 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 36 34 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 32 3a 35 38 3a 35 37 33 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 34 36 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 35 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 36 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 33 3a 30 31 3a 31 37 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 35 38 38 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 35 39 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 36 30 33 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 34 3a 35 38 3a 36 31 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 33 38 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 34 32 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 35 31 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 35 3a 30 31 3a 33 36 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 36 34 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 36 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 38 30 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 36 3a 35 38 3a 37 38 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 30 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 32 32 20 65 78 70 61 6e 64 65 72 3a 20 72 65 63 76 64 20 6d 73 67 20 74 79 70 65 3a 20 32 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 32 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 70 72 6f 63 65 73 73 20 70 63 64 20 73 65 6e 64 20 6d 73 67 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 33 37 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 66 77 72 65 76 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 32 34 38 20 64 65 76 2f 65 78 70 61 6e 64 65 72 2e 31 3a 20 73 65 6e 74 20 73 61 73 61 64 64 72 20 74 6f 20 70 65 65 72 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 39 32 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 30 31 3a 39 33 35 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 30 33 3a 38 34 32 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 35 3a 31 37 3a 34 37 3a 30 34 3a 30 35 32 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 30 20 64 61 74 61 3a 20 31 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 65 34 0a 30 35 3a 31 37 3a 34 37 3a 34 39 3a 34 34 34 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 35 3a 31 37 3a 34 37 3a 34 39 3a 34 35 33 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a diskscan-0.21/libscsicmd/afl/testcase/a4005cb54f820f0dc3889aab343ea1698b1dd5f4.csv000066400000000000000000000024061456470715000261620ustar00rootroot00000000000000,b7 0d 00 00 00 00 00 00 02 00 00 00,,00 0e 00 00 00 00 01 98 00 00 00 00 00 00 00 b6 00 00 00 00 00 00 04 62 00 00 00 00 00 00 00 70 00 00 00 00 00 00 00 98 00 00 00 00 00 00 02 ce 00 00 00 00 00 00 02 14 00 00 00 00 00 00 06 64 00 00 00 00 00 00 05 4a 00 00 00 00 00 00 07 02 00 00 00 00 00 00 04 bc 00 00 00 00 00 00 04 08 00 00 00 00 00 00 04 54 00 00 00 00 00 00 03 98 00 00 00 00 00 00 06 6e 00 00 00 00 00 00 00 9e 00 00 00 00 00 00 03 c0 00 00 00 00 00 00 01 12 00 00 00 00 00 00 02 92 00 00 00 00 00 00 02 a8 00 00 00 00 00 00 02 8c 00 00 00 00 00 00 04 de 00 00 00 00 00 00 03 a2 00 00 00 00 00 00 07 36 00 00 00 00 00 00 07 3e 00 00 00 00 00 00 04 40 00 00 00 00 00 00 05 0e 00 00 00 00 00 00 01 52 00 00 00 00 00 00 02 34 00 00 00 00 00 00 00 36 00 00 00 00 00 00 00 8c 00 00 00 00 00 00 05 b4 00 00 00 00 00 00 01 82 00 00 00 00 00 00 05 36 00 00 00 00 00 00 02 16 00 00 00 00 00 00 06 f2 00 00 00 00 00 00 04 ea 00 00 00 00 00 00 02 86 00 00 00 00 00 00 03 b8 00 00 00 00 00 00 01 60 00 00 00 00 00 00 05 cc 00 00 00 00 00 00 07 56 00 00 00 00 00 00 01 dc 00 00 00 00 00 00 01 3a 00 00 00 00 00 00 05 a0 00 00 00 00 00 00 05 08 00 00 00 00 00 00 01 a6 00 00 00 00 00 00 06 c0 00 00 00 00 00 00 05 d4 00 00 00 00 00 00 05 aa 00 00 00 00 00 00 00 e8 00 00 00 00 00 00 04 24 diskscan-0.21/libscsicmd/afl/testcase/a6b72fc2c30cf1d9ff74a2d5054bcb5dca317c15000066400000000000000000000002001456470715000255650ustar00rootroot00000000000000,25 00 00 00 00 00 00 00 00 00,70 00 06 00 00 00 00 18 00 00 00 00 3f 01 00 00 00 00 00 00 f5 22 00 00 00 00 00 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/a750591769e551117e3144c8927a05d96fdfb362000066400000000000000000000003161456470715000247560ustar00rootroot00000000000000,4d 00 42 00 00 00 00 40 00 00,,02 00 00 36 00 00 00 04 00 00 00 00 00 01 00 04 00 00 00 00 00 02 00 04 00 00 00 00 00 03 00 04 00 00 00 00 00 05 00 0a 00 00 00 00 00 00 00 01 80 00 00 06 00 04 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/b2eeafbc752b681e5d68332192c8097ef43ab687.csv000066400000000000000000000000411456470715000261220ustar00rootroot00000000000000,37 00 08 00 00 00 00 00 08 00,, diskscan-0.21/libscsicmd/afl/testcase/b40a88e1e4a0e0044936b2e61de5364d48b16e8c.csv000066400000000000000000000000251456470715000260200ustar00rootroot00000000000000,1a 00 7f ff ff 00,, diskscan-0.21/libscsicmd/afl/testcase/c144c7638bb08162db1ae53954e6cd20e66474f7000066400000000000000000000030461456470715000251660ustar00rootroot00000000000000,b7 0a 00 00 00 00 00 00 02 00 00 00,,00 83 00 48 01 03 00 08 50 00 cc a0 2b 03 e0 b0 61 93 00 08 50 00 cc a0 2b 03 e0 b2 61 94 00 04 00 00 00 02 61 a3 00 08 50 00 cc a0 2b 03 e0 b3 63 a8 00 18 6e 61 61 2e 35 30 30 30 43 43 41 30 32 42 30 33 45 30 42 33 00 00 00 00 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 03 00 00 00 1c 00 00 02 02 00 00 00 1c 00 00 02 03 00 00 00 1d 00 00 02 02 00 00 00 1d 00 00 02 03 diskscan-0.21/libscsicmd/afl/testcase/ca52cd17cb1a061767830cb4e49867be9b637e56000066400000000000000000000064751456470715000252640ustar00rootroot00000000000000,1c 01 04 40 00 00,,04 00 04 5f 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 30 39 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 31 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 32 39 20 64 65 76 2f 70 68 79 2e 30 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 34 31 20 64 65 76 2f 70 68 79 2e 31 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 35 33 20 64 65 76 2f 70 68 79 2e 32 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 36 32 20 64 65 76 2f 70 68 79 2e 33 3a 20 45 4e 41 42 4c 45 44 2d 3e 44 49 53 41 42 4c 45 44 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 36 37 20 64 65 76 2f 70 68 79 2e 30 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 37 32 20 64 65 76 2f 70 68 79 2e 30 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 38 33 20 64 65 76 2f 70 68 79 2e 30 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 32 38 39 20 64 65 76 2f 70 68 79 2e 30 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 34 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 30 31 20 64 65 76 2f 70 68 79 2e 31 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 30 36 20 64 65 76 2f 70 68 79 2e 31 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 31 30 20 64 65 76 2f 70 68 79 2e 31 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 31 35 20 64 65 76 2f 70 68 79 2e 31 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 35 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 32 37 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 32 38 20 64 65 76 2f 70 68 79 2e 32 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 34 34 20 64 65 76 2f 70 68 79 2e 32 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 34 38 20 64 65 76 2f 70 68 79 2e 32 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 35 32 20 64 65 76 2f 70 68 79 2e 32 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 36 2d 3e 30 78 66 66 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 36 34 20 64 65 76 2f 70 68 79 2e 33 3a 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 36 38 20 64 65 76 2f 70 68 79 2e 33 3a 20 6c 69 6e 6b 20 6e 6f 74 20 72 65 61 64 79 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 37 33 20 64 65 76 2f 70 68 79 2e 33 3a 20 72 61 74 65 20 36 47 2d 3e 75 6e 6b 6e 6f 77 6e 0a 30 33 3a 31 36 3a 35 38 3a 31 32 3a 33 37 38 20 64 65 76 2f 70 68 79 2e 33 3a 20 61 74 74 61 63 68 65 64 20 70 68 79 20 69 64 20 30 78 30 37 2d 3e 30 78 66 66 0a diskscan-0.21/libscsicmd/afl/testcase/ce03e25003a16fc03abb3d4f337a39e622962c60000066400000000000000000000014401456470715000252050ustar00rootroot00000000000000,1c 01 02 40 00 00,,02 00 01 00 00 00 00 00 00 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 11 00 00 00 00 00 00 00 01 00 2f 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 31 00 01 00 33 00 01 00 34 00 01 00 37 00 01 00 34 00 01 00 34 00 01 00 31 00 01 00 31 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 30 00 01 00 2e 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 00 00 00 00 00 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 01 20 00 00 diskscan-0.21/libscsicmd/afl/testcase/d2f9abc5e26020e42b45a32fcf3777cc61ea711c000066400000000000000000000015601456470715000254420ustar00rootroot00000000000000,1a 08 ff ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 03 00 00 00 00 00 00 02 04 03 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 68 59 9c bd 50 01 e6 78 7a c0 e0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 68 59 9c be 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/e71ac2a14ce3dd789a00eae0c656b36e2c07186a000066400000000000000000000001641456470715000254400ustar00rootroot00000000000000,1a 08 3f ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 01 00 00 00 00 00 00 f5 02 00 00 00 00 00 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/ebc80a44e5ef0a66fddb29c48373701b2eeb5227000066400000000000000000000005441456470715000254560ustar00rootroot00000000000000,4d 00 71 00 00 00 00 40 00 00,,31 00 00 68 80 00 03 08 00 00 00 00 00 00 01 bd 80 01 03 08 00 00 00 00 00 00 01 bd 80 02 03 08 00 00 00 00 00 00 01 97 80 03 03 08 00 00 00 00 00 00 01 a6 8f fa 03 08 00 00 00 00 00 00 01 97 8f fb 03 08 00 00 00 00 00 00 01 a6 8f fc 03 04 00 00 00 63 8f fd 03 04 00 00 00 00 8f fe 03 04 00 00 10 70 8f ff 03 04 00 00 74 04 diskscan-0.21/libscsicmd/afl/testcase/ee66ad0b8b05525c54c4538059714a92646c39fb000066400000000000000000000001641456470715000251100ustar00rootroot00000000000000,1c 01 80 40 00 00,,80 00 00 1c 56 45 4e 44 4f 52 20 20 03 01 41 30 35 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/eebceb65beacbe25d0db149e5c37198ee5be1912.csv000066400000000000000000000000701456470715000265440ustar00rootroot00000000000000,25 00 00 00 00 00 00 00 00 00,,00 0e 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/ef22fafdd3041dc08043fe2bb908e96dffa34ff5000066400000000000000000000015641456470715000257060ustar00rootroot00000000000000,37 00 0b 00 00 00 00 02 00 00,,00 0e 01 18 00 00 00 12 00 00 07 75 00 00 00 12 00 00 00 c1 00 00 00 12 00 00 07 4f 00 00 00 12 00 00 01 3d 00 00 00 12 00 00 05 eb 00 00 00 12 00 00 05 bd 00 00 00 12 00 00 07 33 00 00 00 12 00 00 05 23 00 00 00 12 00 00 04 35 00 00 00 12 00 00 06 ed 00 00 00 12 00 00 01 97 00 00 00 12 00 00 02 07 00 00 00 12 00 00 02 2b 00 00 00 12 00 00 03 f5 00 00 00 12 00 00 04 f7 00 00 00 12 00 00 06 cf 00 00 00 12 00 00 04 17 00 00 00 12 00 00 01 0b 00 00 00 12 00 00 02 73 00 00 00 12 00 00 02 35 00 00 00 12 00 00 02 3d 00 00 00 12 00 00 01 31 00 00 00 12 00 00 03 37 00 00 00 12 00 00 06 07 00 00 00 12 00 00 00 5d 00 00 00 12 00 00 06 af 00 00 00 12 00 00 03 dd 00 00 00 12 00 00 00 6f 00 00 00 12 00 00 06 0d 00 00 00 12 00 00 05 9d 00 00 00 12 00 00 04 49 00 00 00 12 00 00 01 f5 00 00 00 12 00 00 06 a1 00 00 00 12 00 00 03 f3 00 00 00 12 00 00 03 55 diskscan-0.21/libscsicmd/afl/testcase/f007593acbf7f63773efa1b65ef61da7fcefbb34000066400000000000000000000001261456470715000257060ustar00rootroot00000000000000,25 00 00 00 00 00 00 00 00 00,70 00 06 00 00 00 00 0a 00 00 00 00 29 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/f3492a44323a0bf7bea4e59b536feaf7620b8e8b000066400000000000000000000004341456470715000254620ustar00rootroot00000000000000,5a 00 3f ff 00 00 00 10 00 00,,00 52 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 00 00 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 00 00 18 06 06 00 00 00 00 00 19 06 16 00 00 0a 00 00 a0 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 21 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/f40e3999c3fe73cd2e50083874537ec000697cb7000066400000000000000000000002001456470715000251110ustar00rootroot00000000000000,25 00 00 00 00 00 00 00 00 00,71 00 04 00 00 00 00 18 00 00 00 00 44 a2 00 00 00 00 00 00 f6 22 00 00 00 00 00 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/f5272bcea41574f9cd663f33334c530abcca01d7000066400000000000000000000012501456470715000253570ustar00rootroot00000000000000,1c 01 01 40 00 00,,01 00 00 d8 00 00 00 00 22 00 06 58 50 01 63 60 01 b6 34 3e 51 55 41 4e 54 41 00 00 4a 42 45 20 49 53 49 4d 37 20 20 20 00 00 00 00 30 31 30 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 17 12 00 10 04 12 00 10 07 01 00 10 0e 01 00 10 18 01 00 10 19 12 00 10 41 72 72 61 79 20 44 65 76 69 63 65 20 20 20 20 54 65 6d 70 65 72 61 74 75 72 65 20 20 20 20 20 45 4d 4d 20 20 20 20 20 20 20 20 20 20 20 20 20 45 6e 63 6c 6f 73 75 72 65 20 20 20 20 20 20 20 45 78 70 61 6e 64 65 72 20 20 20 20 20 20 20 20 43 6f 6e 6e 65 63 74 6f 72 20 20 20 20 20 20 20 diskscan-0.21/libscsicmd/afl/testcase/f7db47bebdfb5888fae0fbe826b37df33a450292000066400000000000000000000030401456470715000256300ustar00rootroot00000000000000,37 00 08 00 00 00 00 00 08 00,,00 0e 00 00 00 00 00 00 00 00 00 0c 00 00 00 70 00 00 00 0c 00 00 00 8e 00 00 00 0c 00 00 01 06 00 00 00 00 00 00 02 02 00 00 00 00 00 00 02 03 00 00 00 01 00 00 02 02 00 00 00 01 00 00 02 03 00 00 00 02 00 00 02 02 00 00 00 02 00 00 02 03 00 00 00 03 00 00 02 02 00 00 00 03 00 00 02 03 00 00 00 04 00 00 02 02 00 00 00 04 00 00 02 03 00 00 00 05 00 00 02 02 00 00 00 05 00 00 02 03 00 00 00 06 00 00 02 02 00 00 00 06 00 00 02 03 00 00 00 07 00 00 02 02 00 00 00 07 00 00 02 03 00 00 00 08 00 00 02 02 00 00 00 08 00 00 02 03 00 00 00 09 00 00 02 02 00 00 00 09 00 00 02 03 00 00 00 0a 00 00 02 02 00 00 00 0a 00 00 02 03 00 00 00 0b 00 00 02 02 00 00 00 0b 00 00 02 03 00 00 00 0c 00 00 02 02 00 00 00 0c 00 00 02 03 00 00 00 0d 00 00 02 02 00 00 00 0d 00 00 02 03 00 00 00 0e 00 00 02 02 00 00 00 0e 00 00 02 03 00 00 00 0f 00 00 02 02 00 00 00 0f 00 00 02 03 00 00 00 10 00 00 02 02 00 00 00 10 00 00 02 03 00 00 00 11 00 00 02 02 00 00 00 11 00 00 02 03 00 00 00 12 00 00 02 02 00 00 00 12 00 00 02 03 00 00 00 13 00 00 02 02 00 00 00 13 00 00 02 03 00 00 00 14 00 00 02 02 00 00 00 14 00 00 02 03 00 00 00 15 00 00 02 02 00 00 00 15 00 00 02 03 00 00 00 16 00 00 02 02 00 00 00 16 00 00 02 03 00 00 00 17 00 00 02 02 00 00 00 17 00 00 02 03 00 00 00 18 00 00 02 02 00 00 00 18 00 00 02 03 00 00 00 19 00 00 02 02 00 00 00 19 00 00 02 03 00 00 00 1a 00 00 02 02 00 00 00 1a 00 00 02 03 00 00 00 1b 00 00 02 02 00 00 00 1b 00 00 02 03 00 00 00 1c 00 00 02 02 00 00 00 1c 00 00 02 03 00 00 00 1d 00 00 02 02 00 00 00 1d 00 00 02 03 diskscan-0.21/libscsicmd/afl/testcase/f7faaa230cdb97e1aec1e5ca75f89b7ea8b78726000066400000000000000000000002271456470715000257140ustar00rootroot00000000000000,25 00 00 00 00 00 00 00 00 00,70 00 03 00 00 00 00 18 00 00 00 00 31 00 03 00 00 00 00 00 03 31 00 03 ff ff ff ff ff ff 00 00,00 83 00 48 01 03 00 08 diskscan-0.21/libscsicmd/afl/testcase/fb0082d5df4c4f237f65ac2c2717ae46408c17b8.csv000066400000000000000000000000541456470715000261060ustar00rootroot00000000000000,1c 01 00 40 00 00,,00 00 00 04 00 3f 40 82 diskscan-0.21/libscsicmd/afl/testcase/fbc7b5cc87f1afa84d70c82f152761258a3b0ca6000066400000000000000000000030461456470715000254560ustar00rootroot00000000000000,b7 0d 00 00 00 00 00 00 00 08 00 00,,00 0e 00 00 00 00 00 00 00 00 00 00 00 00 00 5a 00 00 00 01 00 00 00 5a 00 00 00 02 00 00 00 5a 00 00 00 03 00 00 00 5a 00 00 00 04 00 00 00 5a 00 00 00 06 00 00 00 5a 00 00 00 07 00 00 00 5a 00 00 00 08 00 00 00 5a 00 00 00 09 00 00 00 5a 00 00 00 0a 00 00 00 5a 00 00 00 0b 00 00 00 5a 00 00 00 12 00 00 00 5a 00 00 00 0c 00 00 00 5a 00 00 00 0d 00 00 00 5a 00 00 00 0e 00 00 00 5a 00 00 00 0f 00 00 00 5a 00 00 00 10 00 00 00 5a 00 00 00 05 00 00 00 5a 00 00 00 11 00 00 00 5a 00 00 00 13 00 00 00 5a 00 00 00 1e 00 00 00 5a 00 00 00 14 00 00 00 5a 00 00 00 15 00 00 00 5a 00 00 00 16 00 00 00 5a 00 00 00 17 00 00 00 5a 00 00 00 1f 00 00 00 5a 00 00 00 20 00 00 00 5a 00 00 00 21 00 00 00 5a 00 00 00 22 00 00 00 5a 00 00 00 23 00 00 00 5a 00 00 00 18 00 00 00 5a 00 00 00 19 00 00 00 5a 00 00 00 1a 00 00 00 5a 00 00 00 1b 00 00 00 5a 00 00 00 1c 00 00 00 5a 00 00 00 1d 00 00 00 5a 00 00 00 24 00 00 00 5a 00 00 00 25 00 00 00 5a 00 00 00 26 00 00 00 5a 00 00 00 27 00 00 00 5a 00 00 00 28 00 00 00 5a 00 00 00 29 00 00 00 5a 00 00 00 2a 00 00 00 5a 00 00 00 2d 00 00 00 5a 00 00 00 2e 00 00 00 5a 00 00 00 2f 00 00 00 5a 00 00 00 30 00 00 00 5a 00 00 00 31 00 00 00 5a 00 00 00 32 00 00 00 5a 00 00 00 33 00 00 00 5a 00 00 00 34 00 00 00 5a 00 00 00 35 00 00 00 5a 00 00 00 2b 00 00 00 5a 00 00 00 2c 00 00 00 5a 00 00 00 06 00 00 00 5b 00 00 00 00 00 00 00 5b 00 00 00 01 00 00 00 5b 00 00 00 04 00 00 00 5b 00 00 00 02 00 00 00 5b 00 00 00 03 00 00 00 5b 00 00 00 05 00 00 00 5b 00 00 00 07 00 00 00 5b 00 00 00 38 00 00 00 5a diskscan-0.21/libscsicmd/afl/testcase/fc52fecd84a8f8a478b99b4965333a7f9dfa002c000066400000000000000000000002271456470715000255070ustar00rootroot00000000000000,37 00 11 00 00 00 00 00 08 00,70 00 01 00 00 00 00 18 00 00 00 00 1c 01 00 c0 00 02 00 00 17 47 00 00 00 00 00 00 00 00 00 00,00 16 04 50 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/fcc19a8cc98ada27c4b6a605adca5bb497ad618e000066400000000000000000000001201456470715000257470ustar00rootroot00000000000000,4d 00 4d 00 00 00 00 40 00 00,,0d 00 00 0c 00 00 43 02 00 17 00 01 43 02 00 46 diskscan-0.21/libscsicmd/afl/testcase/fcd8ce757f7d3f54ab0ee3d01007e0a6d70fa288000066400000000000000000000015601456470715000255400ustar00rootroot00000000000000,1a 08 bf ff ff 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 04 00 00 05 24 00 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a c4 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 00 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 14 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 54 97 b0 31 50 01 e6 75 96 b7 10 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 54 97 b0 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/febd83d39f830202ca6081514960b4242e536df7000066400000000000000000000030101456470715000250700ustar00rootroot00000000000000,5a 08 ff ff 00 00 00 10 00 00,,01 f6 00 00 00 00 00 00 81 0a c8 ff ff 00 00 00 ff 00 13 88 82 0e 00 00 00 0a 00 00 00 00 01 00 00 00 00 00 83 16 00 80 00 00 00 00 00 00 00 80 02 00 00 01 00 00 00 00 40 00 00 00 84 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 08 ff ff 00 00 00 00 00 13 88 88 12 14 00 ff ff 00 00 00 00 ff ff 00 08 00 00 00 00 00 00 8a 0a 00 00 00 00 00 00 00 00 07 08 ca 01 00 1c 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 98 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 d9 01 00 64 00 06 01 02 00 00 00 00 21 1a 02 02 50 00 03 96 9c 89 bf e2 50 06 04 80 78 0f c3 3f 0e 00 00 00 00 00 00 00 88 bb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 21 1a 02 02 50 00 03 96 9c 89 bf e3 50 06 04 80 78 0e dc bf 20 00 00 00 00 00 00 00 88 bb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 d9 02 00 0c 00 06 00 00 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 01 02 00 00 00 10 80 ab 00 00 80 af 00 01 c0 a8 00 01 00 00 0a 00 00 01 00 10 80 ab 00 00 80 af 00 01 c0 a8 00 01 00 00 0a 00 9a 26 00 02 00 00 00 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 08 da 01 00 0c 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 08 00 00 00 00 00 00 00 00 01 a4 0e 00 00 40 37 0f 13 00 00 00 00 00 00 00 00 e4 01 00 0c 00 00 00 00 00 00 00 00 00 00 00 00 c0 01 00 30 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/fec38c54692c2fcff269370fc1bbb9e598b821a7000066400000000000000000000001641456470715000255040ustar00rootroot00000000000000,1a 00 7f ff ff 00,70 00 02 00 00 00 00 18 00 00 00 00 04 04 00 80 30 9e 00 00 f5 04 00 00 00 00 00 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/fec50c6c3f5486958b33beada06857deeff177dd.csv000066400000000000000000000006541456470715000264430ustar00rootroot00000000000000,12 00 00 02 00 00,,0d 00 06 12 83 00 d0 02 45 4d 43 20 20 20 20 20 45 53 45 53 20 45 6e 63 6c 6f 73 75 72 65 20 20 30 30 30 31 50 4d 43 53 49 45 52 41 80 05 02 00 00 00 00 00 00 00 00 00 00 00 00 75 0c 00 03 01 03 e0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 03 00 00 00 01 41 50 4d 30 30 31 34 30 37 32 34 32 36 38 00 00 diskscan-0.21/libscsicmd/afl/testcase/fedb716d47c930bafffff38b6c274ce9202187ac000066400000000000000000000014211456470715000256270ustar00rootroot00000000000000,1a 08 bf ff ff 00,,00 0e 00 00 00 00 00 00 00 00 00 03 00 00 00 2c 00 00 00 00 00 00 00 5a 00 00 00 01 00 00 00 5a 00 00 00 02 00 00 00 5a 00 00 00 03 00 00 00 5a 00 00 00 04 00 00 00 5a 00 00 00 06 00 00 00 5a 00 00 00 07 00 00 00 5a 00 00 00 08 00 00 00 5a 00 00 00 09 00 00 00 5a 00 00 00 0a 00 00 00 5a 00 00 00 0b 00 00 00 5a 00 00 00 12 00 00 00 5a 00 00 00 0c 00 00 00 5a 00 00 00 0d 00 00 00 5a 00 00 00 0e 00 00 00 5a 00 00 00 0f 00 00 00 5a 00 00 00 10 00 00 00 5a 00 00 00 05 00 00 00 5a 00 00 00 11 00 00 00 5a 00 00 00 13 00 00 00 5a 00 00 00 1e 00 00 00 5a 00 00 00 14 00 00 00 5a 00 00 00 15 00 00 00 5a 00 00 00 16 00 00 00 5a 00 00 00 17 00 00 00 5a 00 00 00 1f 00 00 00 5a 00 00 00 20 00 00 00 5a 00 00 00 21 00 00 00 5a 00 00 00 22 00 00 00 5a 00 00 00 23 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/ff0232f5144d65579feeccb6b65687c5056501a7000066400000000000000000000002441456470715000251730ustar00rootroot00000000000000,4d 00 77 00 00 00 00 40 00 00,,37 00 00 28 00 00 02 04 4a 92 79 ba 00 01 02 04 71 dd 1f cd 00 02 02 04 6d 2c da 32 00 03 02 04 01 87 03 91 00 04 02 04 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/ff3242c96b948a6ded16dd8ae51b1e61c40c5a66000066400000000000000000000002441456470715000254610ustar00rootroot00000000000000,1a 00 bf ff ff 00,70 00 05 00 00 00 00 28 00 00 00 00 24 00 00 c0 00 04 00 1a 13 01 01 00 00 00 00 00 00 00 78 00 00 1d 31 1a 18 00 00 00 00 00 14 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/ff5a0c3111af229b7f4ec8c4a38d82ccf7e553a2000066400000000000000000000015601456470715000255340ustar00rootroot00000000000000,1a 08 3f ff ff 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 c0 00 04 00 00 05 24 00 00 ff ff ff ff ff ff 00 00,01 aa 00 10 01 00 00 10 00 00 00 00 68 cb 9e 30 00 00 00 00 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 00 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 14 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 70 c8 b6 d5 50 01 e6 78 ea fa c0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 70 c8 b6 d6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/ff5f50f7b5d36b765da768ef583a8b289be09a7e.csv000066400000000000000000000002001456470715000263020ustar00rootroot00000000000000,1a 08 3f ff ff 00,,23 00 10 00 08 12 10 00 ff ff 00 00 ff ff ff ff 00 ff 00 00 00 00 00 00 1c 0a 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/ff82315f17a9d582afd6aba974c222e00d14af15000066400000000000000000000002001456470715000253560ustar00rootroot00000000000000,4d 00 5f d2 00 00 00 40 00 00,70 00 05 00 00 00 00 18 00 00 00 00 24 00 00 cd 00 02 00 00 f8 23 00 00 00 00 00 00 00 00 00 00, diskscan-0.21/libscsicmd/afl/testcase/ff980b7b6e39f929b8ddb08e419a2904abd44b33000066400000000000000000000020071456470715000254150ustar00rootroot00000000000000,1c 01 04 40 00 00,,04 00 01 4d 32 34 3a 31 35 3a 31 31 3a 31 37 3a 30 30 30 20 74 6e 6c 2f 74 75 6e 6e 65 6c 5f 73 74 65 5f 72 65 63 76 5f 64 69 61 67 5f 6d 73 67 5f 68 61 6e 64 6c 65 72 3a 20 74 75 6e 6e 65 6c 69 6e 67 20 52 45 43 56 20 44 49 41 47 4e 4f 53 54 49 43 20 72 65 63 65 69 76 65 64 20 66 72 6f 6d 20 53 54 45 2e 0a 32 34 3a 31 35 3a 31 31 3a 31 37 3a 32 30 33 20 45 53 45 53 3a 20 66 77 64 6c 20 70 72 74 74 6e 20 63 6e 74 72 6c 20 73 74 61 74 75 73 20 72 65 63 65 69 76 65 64 3a 20 61 63 74 69 76 65 3a 20 31 20 64 61 74 61 3a 20 30 20 69 6d 67 30 63 72 63 3a 20 30 78 62 64 20 69 6d 67 31 63 72 63 3a 20 30 78 61 34 0a 32 34 3a 31 35 3a 31 31 3a 32 35 3a 31 38 30 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a 32 34 3a 31 35 3a 31 31 3a 32 35 3a 31 38 38 20 45 4d 43 20 53 54 45 3a 20 54 6f 74 61 6c 20 6e 75 6d 62 65 72 20 6f 66 20 56 50 44 20 70 61 67 65 73 20 77 61 73 20 31 30 2c 20 6e 6f 77 20 31 30 0a diskscan-0.21/libscsicmd/afl/testcase/ffb313726fc6fa8b68381e5df22e960cb623b62c.csv000066400000000000000000000002221456470715000261740ustar00rootroot00000000000000,9e 10 00 00 00 00 00 00 00 00 00 00 02 00 00 00,,00 00 00 00 00 e7 bf ff 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/ffe9cd6ca4dbbdd2b2429c8d8023183b84c2962f000066400000000000000000000002601456470715000255430ustar00rootroot00000000000000,12 01 88 02 00 00,,00 88 00 30 00 00 00 01 00 00 00 00 00 00 00 0c 61 93 00 08 50 00 c5 00 67 b9 53 ad 00 00 00 02 00 00 00 00 00 00 00 0c 61 93 00 08 50 00 c5 00 67 b9 53 ae diskscan-0.21/libscsicmd/afl/testcase/ffefa3f6034cc5680792a8cae855bc7a2d9f9019000066400000000000000000000002141456470715000254760ustar00rootroot00000000000000,12 01 c0 02 00 00,,0d c0 00 24 01 00 00 00 24 00 00 00 66 2f e0 06 0d 00 04 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 23 4a 88 75 diskscan-0.21/libscsicmd/afl/testcase/fff9db19407d43fdb18735c075071a866a5f0795000066400000000000000000000005521456470715000252030ustar00rootroot00000000000000,1c 01 82 40 00 00,,82 00 00 6e 48 49 54 41 43 48 49 20 43 32 36 30 00 01 00 00 00 00 00 00 0b 08 00 00 00 00 00 00 00 01 00 01 00 00 00 00 00 0e 00 01 00 01 00 00 00 5f 00 02 00 00 00 00 00 0b 00 02 00 01 00 00 00 11 00 03 00 00 00 00 00 00 00 03 00 01 00 00 00 00 00 04 00 00 00 00 00 00 00 04 00 01 00 00 00 00 00 05 00 00 00 00 00 0e 00 05 00 01 00 00 00 50 diskscan-0.21/libscsicmd/afl/testcase/fffa5f13587a7e46023238c9e7db91fd61414105000066400000000000000000000014211456470715000251640ustar00rootroot00000000000000,1a 00 bf ff ff 00,,bf 00 10 08 2e 90 ed d0 00 00 02 00 81 0a 04 01 00 00 00 00 00 00 0c 00 82 0e 00 00 00 00 00 00 01 f4 00 00 00 00 00 00 03 16 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 40 00 00 00 04 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 87 0a 04 01 00 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 00 00 00 00 00 00 00 00 8a 0a 00 10 00 00 00 00 00 00 00 06 ca 01 00 1c 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 98 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 d9 01 00 64 00 06 02 02 00 00 00 00 21 0a 02 02 50 00 cc a0 13 07 16 b1 50 06 04 80 d8 12 41 bf 18 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 21 0a 02 02 50 00 cc diskscan-0.21/libscsicmd/afl/testcase/id:000001,sig:11,src:005156,op:ext_AO,pos:34000066400000000000000000000004501456470715000262240ustar00rootroot00000000000000,1C 00 43 00 00 00 00 40 00 00,,01 aa 00 54 00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00B00030 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 00 73 e0 f6 d9 46 00 00 06 00 08 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000001,src:000141,op:arith8,pos:118,val:-34000066400000000000000000000002341456470715000263760ustar00rootroot00000000000000,5a 10 300,,00 2e 00 10 01 00 00 18 00 00 00 00 00 e7 bf ff 00 00 00 00 00 00 02 00 08 12 10 00 ff ff 00 00 ff ff ff fD 00 ff 00 00 00 00 00 00 1c 0a 00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000002,src:000200,op:ext_AO,pos:571000066400000000000000000000024141456470715000252630ustar00rootroot00000000000000,5a 00 bf ff 00 00 00 10 00 00,,01 a2 00 10 00 00 00 08 68 cb 9e 30 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 0B 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 64 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 ff fd f2 f1 50 01 e6 77 5a 4d b0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 5f 0d f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 02 00 0c 00 06 03 e8 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 00 02 00 00 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 09 00 00 01 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 00 00 9a 26 00 00 00 00 00 0a 00 00 8c a0 00 00 17 70 00 00 46 50 00 00 46 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 00 04 00 00 00 00 00 00 00 01 dc 01 00 0c 01 00 00 48 00 18 01 f4 00 00 00 00 80 16 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000003,src:000314,op:flip1,pos:19000066400000000000000000000002401456470715000250360ustar00rootroot00000000000000,5a 10 3f ff00,,00 0e 40 10 01 00 00 10 00 00 00 00 00 e7 bf ff 00 00 00 00 00 00 d2 00 08 00 ff ff ff ff ff ffff 0000 ff 00 00 ff ff 00 ff 00 00 00 00 00 00 1diskscan-0.21/libscsicmd/afl/testcase/id:000005,sig:11,src:005234,op:havoc,rep:2000066400000000000000000000002101456470715000260400ustar00rootroot00000000000000,1C 00 43 00 00 00 00,,01 00000E00000000000000000000 0000 01 00 08 00 00 00 E0 00 00 00 00 00 02 00 08 00 00 00 00 00 00B00030 00 0diskscan-0.21/libscsicmd/afl/testcase/id:000005,src:000445,op:flip1,pos:132000066400000000000000000000002401456470715000251210ustar00rootroot00000000000000,5a 10 3f ff00,,00 2e 00 10 01 00 00 10 00 00 00 00 00 e7 bd ff 00 00 00 00 00 00 08 12 10 09 ff ff 00 02 00 0810 00 ff ff ff ff fd 00 ff 00 00 0000 00 1c 0a diskscan-0.21/libscsicmd/afl/testcase/id:000007,sig:11,src:005483,op:flip2,pos:43000066400000000000000000000004501456470715000260720ustar00rootroot00000000000000,12 01 43 00 00 00 00 40 00 00,,03 40 00 54,00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00B00030 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 00 73 e0 f6 d9 46 00 00 06 00 08 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000008,src:001208,op:flip1,pos:89000066400000000000000000000001541456470715000250610ustar00rootroot00000000000000,1a 08 300,,23 00 10 00 08 12 1F 00 ff ff 00 00 ff ff ff ff 00 ff 00 00 00 00 00fffffffffdffffffffffff00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000013,sig:11,src:005882,op:havoc,rep:2000066400000000000000000000001601456470715000260540ustar00rootroot00000000000000,1A 00 43 00 40 00 00 40 00 00,,03 00 00 08 00 00 00 00 00 00 00 00  0 0M 0 00 00diskscan-0.21/libscsicmd/afl/testcase/id:000015,src:001216,op:flip1,pos:229000066400000000000000000000004041456470715000251300ustar00rootroot00000000000000,5a 20 3f ff00 00 10 00 00,,00 52 00 00 00 00 00 00 02 0e 00 00 00 00 00 00 40 00 00 09 00 00 00 00 0a 0a 00 00 00 00 00 00 00 00 0ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffdfffffff0 00 18 06fffffffffffffdiskscan-0.21/libscsicmd/afl/testcase/id:000018,sig:11,src:001807,op:flip1,pos:93000066400000000000000000000130501456470715000260740ustar00rootroot00000000000000,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 94 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000018,src:001179,op:ext_AO,pos:826000066400000000000000000000024141456470715000253150ustar00rootroot00000000000000,5a 00 bf ff 00 00 00 10 00 00,,01 a2 00 10 00 00 00 08 68 cb 9e 30 00 00 02 00 81 0a 04 14 ff 00 00 00 05 00 0c 00 82 0e 00 00 00 00 00 00 00 00 01 3a 00 00 00 00 83 16 bb d0 00 00 00 00 03 80 04 c4 02 08 00 01 00 a0 00 18 40 00 00 00 84 16 02 d3 c1 06 00 00 00 00 00 00 00 00 00 00 00 00 00 00 27 31 00 00 87 0a 04 14 ff 00 00 00 00 00 0c 00 88 12 10 00 ff ff 00 00 ff ff ff ff 80 03 00 00 00 00 00 00 8a 0a 00 10 00 80 00 00 00 00 00 06 18 06 06 00 00 00 00 00 99 0e 06 00 23 28 1b 58 00 00 00 00 00 00 00 00 59 01 00 65 00 06 00 02 00 00 00 00 10 49 0e 00 50 00 c5 00 5f 0d f2 f1 50 01 e6 77 5a 4d b0 00 01 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 00 00 50 00 c5 00 5f 0d f2 f2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 88 aa 00 00 00 00 00 00 00 00 00 00 00 00 00 00 59 ff ff fd 00 06 03 e8 00 00 00 00 00 00 00 00 59 03 00 2c 00 06 00 02 00 00 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 09 00 00 01 00 10 80 ac 00 01 80 ac 00 01 00 00 00 00 00 00 00 00 9a 26 00 00 00 00 00 0a 00 00 8c a0 00 00 17 70 00 00 46 50 00 00 46 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 9c 0a 00 04 00 00 00 00 00 00 00 01 dc 01 00 0c 01 00 00 48 00 18 01 f4 00 00 00 00 80 16 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0c 00 00 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000019,sig:11,src:001807,op:flip1,pos:670000066400000000000000000000130501456470715000261560ustar00rootroot00000000000000,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 16 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000019,src:001231,op:flip1,pos:72000066400000000000000000000003241456470715000250460ustar00rootroot00000000000000,5a 00,,00 59 00 00 00 00 00 0B 02 0e 00 00 00 00 00 00 00 00 00 FFFFFFFDFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFdiskscan-0.21/libscsicmd/afl/testcase/id:000020,sig:11,src:001807,op:flip1,pos:2325000066400000000000000000000130501456470715000262250ustar00rootroot00000000000000,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 14 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 94 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/id:000021,sig:11,src:001807,op:flip2,pos:238000066400000000000000000000130501456470715000261500ustar00rootroot00000000000000,4d 00 55 00 00 00 00,,95 00 07 60 00 00 03 0c 00 0e ad cb 00 08 02 32 00 00 02 32 00 01 03 14 00 00 d8 00 13 11 00 01 e7 50 03 91 00 00 00 00 4a 26 37 51 00 02 03 14 00 01 e9 72 13 11 00 40 2b 52 02 8d 00 00 00 00 07 9f 84 21 00 03 03 12 00 02 22 c6 51 17 01 42 c5 b9 01 a9 00 00 00 00 66 25 50 00 00 04 03 14 00 02 27 74 51 17 01 41 f0 e7 00 6e 00 00 00 00 4d dd e2 00 00 05 03 14 00 02 30 a0 13 11 00 30 ff 76 03 41 00 00 00 00 29 9a 7c 93 00 06 03 14 00 02 42 cf 13 11 00 50 45 63 04 c2 00 00 00 00 0c 30 a4 fc 00 07 03 14 00 03 d9 dd 13 11 00 10 d6 c8 04 28 00 00 00 00 25 5d 1f a2 00 08 03 14 00 06 69 3a 51 17 01 50 19 fb 03 97 00 00 00 00 04 c3 f6 00 00 09 03 14 00 07 c0 13 51 17 01 52 94 3f 01 31 00 00 00 00 5e fc 5d e2 00 0a 03 14 00 08 79 da 51 17 01 42 c4 56 02 6f 00 00 00 00 65 fd 2d a6 00 0b 03 14 00 09 ed 76 51 17 01 52 88 b3 00 41 00 00 00 00 5d c1 81 dc 00 0c 03 14 00 0a 55 83 51 17 01 12 31 4f 00 4c 00 00 00 00 55 d9 f2 c0 00 0d 03 14 00 0a 55 94 51 17 01 02 7b fe 03 4d 00 00 00 00 5b ad f8 43 00 0e 03 14 00 0a 55 94 51 17 01 02 7b fe 03 52 00 00 00 00 5b ad f8 48 00 0f 03 14 00 0a 55 94 51 17 01 02 7b fe 03 57 00 00 00 00 5b ad f8 4d 00 10 03 14 00 0a 55 94 51 17 01 02 7b fe 03 62 00 00 00 00 5b ad f8 58 00 11 03 14 00 0a 55 94 51 17 01 02 7b fe 03 63 00 00 00 00 5b ad f8 59 00 12 03 14 00 0a 55 94 51 17 01 02 7b fe 03 64 00 00 00 00 5b ad f8 5a 00 13 03 14 00 0a 55 94 51 17 01 02 7b fe 03 6e 00 00 00 00 5b ad f8 64 00 14 03 14 00 0a 55 94 51 18 01 02 7b fe 03 71 00 00 00 00 5b ad f8 67 00 15 03 14 00 0a 55 94 51 17 01 02 7b fe 03 76 00 00 00 00 5b ad f8 6c 00 16 03 14 00 0a 55 94 51 17 01 02 7b fe 03 81 00 00 00 00 5b ad f8 77 00 17 03 14 00 0a 55 94 51 17 01 02 7b fe 03 82 00 00 00 00 5b ad f8 78 00 18 03 14 00 0a 55 9a 51 17 01 02 7b fe 03 83 00 00 00 00 5b ad f8 79 00 19 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 84 00 00 00 00 5b ad f8 7a 00 1a 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 85 00 00 00 00 5b ad f8 7b 00 1b 03 14 00 0a 55 e5 51 18 01 02 7b fe 03 8d 00 00 00 00 5b ad f8 83 00 1c 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8e 00 00 00 00 5b ad f8 84 00 1d 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 8f 00 00 00 00 5b ad f8 85 00 1e 03 14 00 0a 55 e5 51 17 01 02 7b fe 03 90 00 00 00 00 5b ad f8 86 00 1f 03 14 00 0a 56 87 13 11 00 02 7b fe 03 91 00 00 00 00 5b ad f8 87 00 20 03 14 00 0a 56 87 13 11 00 02 7b fe 03 92 00 00 00 00 5b ad f8 88 00 21 03 14 00 0a 56 87 51 18 01 02 7b fe 03 93 00 00 00 00 5b ad f8 89 00 22 03 14 00 0a 56 87 51 17 01 02 7b fe 03 94 00 00 00 00 5b ad f8 8a 00 23 03 14 00 0a 56 87 13 11 00 02 7b fe 03 95 00 00 00 00 5b ad f8 8b 00 24 03 14 00 0a 56 87 51 17 01 02 7b fe 03 96 00 00 00 00 5b ad f8 8c 00 25 03 14 00 0a 56 87 51 17 01 02 7b fe 03 97 00 00 00 00 5b ad f8 8d 00 26 03 14 00 0a 56 87 51 17 01 02 7b fe 03 99 00 00 00 00 5b ad f8 8f 00 27 03 14 00 0a 56 e0 13 11 00 02 7b fe 03 9a 00 00 00 00 5b ad f8 90 00 28 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 9f 00 00 00 00 5b ad f8 95 00 29 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 a4 00 00 00 00 5b ad f8 9a 00 2a 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a5 00 00 00 00 5b ad f8 9b 00 2b 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a6 00 00 00 00 5b ad f8 9c 00 2c 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 a7 00 00 00 00 5b ad f8 9d 00 2d 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b4 00 00 00 00 5b ad f8 aa 00 2e 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 b5 00 00 00 00 5b ad f8 ab 00 2f 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 b6 00 00 00 00 5b ad f8 ac 00 30 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c7 00 00 00 00 5b ad f8 bd 00 31 03 14 00 0a 56 e0 51 17 01 02 7b fe 03 c8 00 00 00 00 5b ad f8 be 00 32 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 c9 00 00 00 00 5b ad f8 bf 00 33 03 14 00 0a 56 e0 51 18 01 02 7b fe 03 ca 00 00 00 00 5b ad f8 c0 00 34 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 56 00 00 00 00 5b ad fc c8 00 35 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 57 00 00 00 00 5b ad fc c9 00 36 03 14 00 0a 56 e0 51 18 01 02 7b ff 03 80 00 00 00 00 5b ad fc f2 00 37 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 84 00 00 00 00 5b ad fc f6 00 38 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 86 00 00 00 00 5b ad fc f8 00 39 03 14 00 0a 56 e0 51 17 01 02 7b ff 03 87 00 00 00 00 5b ad fc f9 00 3a 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 88 00 00 00 00 5b ad fc fa 00 3b 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 89 00 00 00 00 5b ad fc fb 00 3c 03 14 00 0a 57 8b 51 18 01 02 7b ff 03 95 00 00 00 00 5b ad fd 07 00 3d 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 96 00 00 00 00 5b ad fd 08 00 3e 03 14 00 0a 57 8b 51 17 01 02 7b ff 03 97 00 00 00 00 5b ad fd 09 00 3f 03 14 00 0a 57 8b 51 18 01 02 7c 00 03 7b 00 00 00 00 5b ae 01 68 00 40 03 14 00 0a 57 b9 13 11 00 02 7c 00 03 7c 00 00 00 00 5b ae 01 69 00 41 03 14 00 0a 5e 51 51 17 01 02 7c 00 03 69 00 00 00 00 5b ae 01 56 00 42 03 14 00 0a 67 7a 51 17 01 02 7b ff 03 a4 00 00 00 00 5b ad fd 16 00 43 03 14 00 0a 73 09 51 17 01 02 7b ff 03 85 00 00 00 00 5b ad fc f7 00 44 03 14 00 0a 79 20 51 17 01 02 7c 00 03 68 00 00 00 00 5b ae 01 55 00 45 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 b3 00 00 00 00 5b ad f8 a9 00 46 03 14 00 0a 85 b4 51 17 01 02 7b fe 03 cb 00 00 00 00 5b ad f8 c1 00 47 03 14 00 0a 8a 35 51 17 01 02 7b ff 03 64 00 00 00 00 5b ad fc d6 00 48 03 14 00 0a 9a da 51 17 01 02 7b ff 035b ad fc d7 00 49 03 14 00 0a d5 f7 51 17 01 02 7b ff 03 83 00 00 00 00 5b ad fc f5 00 4a 03 14 00 0a e8 64 51 17 01 02 7b fe 03 4a 00 00 00 00 5b ad f8 40 00 4b 03 14 00 0a e8 64 51 17 01 02 7c 00 03 38 00 00 00 00 5b ae 01 25 00 4c 03 14 00 0b b3 10 51 17 01 32 a3 06 01 d6 00 00 00 00 5f 89 3d 79 00 4d 03 14 00 0b b3 10 51 17 01 32 a3 0a 01 6a 00 00 00 00 5f 89 4f 6d 00 4e 03 14 00 0c a0 61 51 17 01 33 00 9e 02 e8 00 00 00 00 diskscan-0.21/libscsicmd/afl/testcase/log_sense_9bd3419f85d952cf54a38196fc0775a2bfa4c6ff.csv000066400000000000000000000007041456470715000302560ustar00rootroot00000000000000,4d 00 55 00 00 00 00 40 00 00,,95 00 00 88 00 00 03 0c 00 0f 17 2b 00 08 02 5d 00 00 02 5d 00 01 03 14 00 03 7f bf 51 18 01 50 5b 54 03 48 00 00 00 00 11 57 80 1b 00 02 03 14 00 0c 68 1c 13 11 00 20 44 4c 03 9d 00 00 00 00 0b 8f 13 7a 00 03 03 14 00 0c 6c da 51 17 01 20 9d ef 05 26 00 00 00 00 1a 25 64 00 00 04 03 14 00 0c f2 ec 51 17 01 21 f2 bd 04 4a 00 00 00 00 4a cf 77 f7 00 05 03 14 00 0d ab 1d 51 17 01 21 89 2a 03 75 00 00 00 00 3c f7 ac 00 diskscan-0.21/libscsicmd/afl/testcase/log_sense_ac03383386fa3d77d3d460480a52e0b99a1c580e.csv000066400000000000000000000002301456470715000277750ustar00rootroot00000000000000,4d 00 7e 00 00 00 00 40 00 00,,3e 00 00 24 00 00 02 04 00 10 c8 20 00 08 02 04 00 00 00 10 00 09 02 04 00 00 00 3c 00 0e 02 08 00 00 3c 04 24 09 8b 7d diskscan-0.21/libscsicmd/afl/testcase/log_sense_c52c16bd44de5cf72ba1a55c0b6258349a74e5d6.csv000066400000000000000000000001371456470715000302230ustar00rootroot00000000000000,4d 00 40 00 00 00 00 40 00 00,,00 00 00 11 00 02 03 05 06 0d 0e 0f 10 11 15 18 1a 2f 30 31 37 diskscan-0.21/libscsicmd/afl/testcase/log_sense_d192aef3ac66f84b8996edeb95ef1e7e9d6660cb.csv000066400000000000000000000001311456470715000305040ustar00rootroot00000000000000,4d 00 40 00 00 00 00 40 00 00,,00 00 00 0f 00 02 03 05 06 0d 0e 0f 10 11 15 18 1a 2f 31 diskscan-0.21/libscsicmd/afl/testcase/log_sense_dc08fbd86ddd3f34a56532faf9b46f0ae135e644.csv000066400000000000000000000003401456470715000303710ustar00rootroot00000000000000,4d 00 6f 00 00 00 00 40 00 00,,2f 00 00 3c 00 00 03 08 00 00 19 55 21 00 00 00 00 01 03 04 5d 53 00 00 00 02 03 04 5d 54 00 00 00 03 03 04 5d 28 00 00 00 04 03 04 0b 06 00 00 00 05 03 04 5d 55 00 00 00 06 03 04 5d 56 00 00 diskscan-0.21/libscsicmd/afl/testcase/log_sense_f2ca65053fcb0a0b0a479e181fa8b497beb40d9c.csv000066400000000000000000000003101456470715000303440ustar00rootroot00000000000000,4d 00 4e 00 00 00 00 40 00 00,,0e 00 00 34 00 01 01 06 32 30 31 33 34 37 00 02 01 06 32 30 31 33 34 37 00 03 03 04 00 00 27 10 00 04 03 04 00 00 05 53 00 05 03 04 00 04 93 e0 00 06 03 04 00 00 05 53 diskscan-0.21/libscsicmd/afl/testcase/log_sense_fb4080b69b8ca7d50d16f424305467a18d8eded9.csv000066400000000000000000000001041456470715000301520ustar00rootroot00000000000000,4d 00 46 00 00 00 00 40 00 00,,06 00 00 08 00 00 02 04 00 00 02 44 diskscan-0.21/libscsicmd/afl/testcase/log_sense_fc58600bcf8dc103f911bb2a6a867ab2c8e42fe2.csv000066400000000000000000000004201456470715000303510ustar00rootroot00000000000000,4d 00 6f 00 00 00 00 40 00 00,,2f 00 00 4c 00 00 03 08 00 00 1c 46 26 00 00 00 00 01 03 04 5d 53 00 00 00 02 03 04 5d 54 00 00 00 03 03 04 5d 57 00 00 00 04 03 04 5d 28 00 00 00 05 03 04 0b 06 01 00 00 06 03 04 5d 56 38 00 00 07 03 04 5d 55 00 00 00 08 03 04 5d 20 00 00 diskscan-0.21/libscsicmd/afl/testcase/log_sense_ffe62c433d9a885d2a5670ff890f5b00089739aa.csv000066400000000000000000000005001456470715000301040ustar00rootroot00000000000000,4d 00 59 00 00 00 00 40 00 00,,19 00 00 5c 00 01 02 40 00 00 00 05 1d 74 16 f0 00 00 00 04 62 22 c5 8d 00 00 00 43 98 00 04 2c 00 00 00 53 be 7d 55 4d 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 02 08 00 00 00 00 01 b4 c1 aa 00 03 03 08 00 00 00 02 00 00 00 05 diskscan-0.21/libscsicmd/afl/testcase/log_sense_ffee0af0b99b68b9d287e6f65ad08a4e11967daa.csv000066400000000000000000000004501456470715000304700ustar00rootroot00000000000000,4d 00 43 00 00 00 00 40 00 00,,03 00 00 54 00 00 00 08 00 00 00 00 00 00 00 00 00 01 00 08 00 00 00 00 00 00 00 00 00 02 00 08 00 00 00 00 00 00 00 00 00 03 00 08 00 00 00 00 00 00 00 00 00 04 00 08 00 00 00 00 00 00 00 00 00 05 00 08 00 01 69 53 90 5e 44 00 00 06 00 08 00 00 00 00 00 00 00 00 diskscan-0.21/libscsicmd/include/000077500000000000000000000000001456470715000170035ustar00rootroot00000000000000diskscan-0.21/libscsicmd/include/asc_num_list.h000066400000000000000000001301611456470715000216360ustar00rootroot00000000000000#ifndef LIBSCSICMD_ASC_NUM_LIST_H #define LIBSCSICMD_ASC_NUM_LIST_H #define ASC_NUM_LIST \ SENSE_CODE(0x0, 0x0, "NO ADDITIONAL SENSE INFORMATION") \ SENSE_CODE(0x0, 0x1, "FILEMARK DETECTED") \ SENSE_CODE(0x0, 0x2, "END-OF-PARTITION/MEDIUM DETECTED") \ SENSE_CODE(0x0, 0x3, "SETMARK DETECTED") \ SENSE_CODE(0x0, 0x4, "BEGINNING-OF-PARTITION/MEDIUM DETECTED") \ SENSE_CODE(0x0, 0x5, "END-OF-DATA DETECTED") \ SENSE_CODE(0x0, 0x6, "I/O PROCESS TERMINATED") \ SENSE_CODE(0x0, 0x7, "PROGRAMMABLE EARLY WARNING DETECTED") \ SENSE_CODE(0x0, 0x11, "AUDIO PLAY OPERATION IN PROGRESS") \ SENSE_CODE(0x0, 0x12, "AUDIO PLAY OPERATION PAUSED") \ SENSE_CODE(0x0, 0x13, "AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED") \ SENSE_CODE(0x0, 0x14, "AUDIO PLAY OPERATION STOPPED DUE TO ERROR") \ SENSE_CODE(0x0, 0x15, "NO CURRENT AUDIO STATUS TO RETURN") \ SENSE_CODE(0x0, 0x16, "OPERATION IN PROGRESS") \ SENSE_CODE(0x0, 0x17, "CLEANING REQUESTED") \ SENSE_CODE(0x0, 0x18, "ERASE OPERATION IN PROGRESS") \ SENSE_CODE(0x0, 0x19, "LOCATE OPERATION IN PROGRESS") \ SENSE_CODE(0x0, 0x1a, "REWIND OPERATION IN PROGRESS") \ SENSE_CODE(0x0, 0x1b, "SET CAPACITY OPERATION IN PROGRESS") \ SENSE_CODE(0x0, 0x1c, "VERIFY OPERATION IN PROGRESS") \ SENSE_CODE(0x0, 0x1d, "ATA PASS THROUGH INFORMATION AVAILABLE") \ SENSE_CODE(0x0, 0x1e, "CONFLICTING SA CREATION REQUEST") \ SENSE_CODE(0x0, 0x1f, "LOGICAL UNIT TRANSITIONING TO ANOTHER POWER CONDITION") \ SENSE_CODE(0x0, 0x20, "EXTENDED COPY INFORMATION AVAILABLE") \ SENSE_CODE(0x0, 0x21, "ATOMIC COMMAND ABORTED DUE TO ACA") \ SENSE_CODE(0x1, 0x0, "NO INDEX/SECTOR SIGNAL") \ SENSE_CODE(0x2, 0x0, "NO SEEK COMPLETE") \ SENSE_CODE(0x3, 0x0, "PERIPHERAL DEVICE WRITE FAULT") \ SENSE_CODE(0x3, 0x1, "NO WRITE CURRENT") \ SENSE_CODE(0x3, 0x2, "EXCESSIVE WRITE ERRORS") \ SENSE_CODE(0x4, 0x0, "LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE") \ SENSE_CODE(0x4, 0x1, "LOGICAL UNIT IS IN PROCESS OF BECOMING READY") \ SENSE_CODE(0x4, 0x2, "LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED") \ SENSE_CODE(0x4, 0x3, "LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED") \ SENSE_CODE(0x4, 0x4, "LOGICAL UNIT NOT READY, FORMAT IN PROGRESS") \ SENSE_CODE(0x4, 0x5, "LOGICAL UNIT NOT READY, REBUILD IN PROGRESS") \ SENSE_CODE(0x4, 0x6, "LOGICAL UNIT NOT READY, RECALCULATION IN PROGRESS") \ SENSE_CODE(0x4, 0x7, "LOGICAL UNIT NOT READY, OPERATION IN PROGRESS") \ SENSE_CODE(0x4, 0x8, "LOGICAL UNIT NOT READY, LONG WRITE IN PROGRESS") \ SENSE_CODE(0x4, 0x9, "LOGICAL UNIT NOT READY, SELF-TEST IN PROGRESS") \ SENSE_CODE(0x4, 0xa, "LOGICAL UNIT NOT ACCESSIBLE, ASYMMETRIC ACCESS STATE TRANSITION") \ SENSE_CODE(0x4, 0xb, "LOGICAL UNIT NOT ACCESSIBLE, TARGET PORT IN STANDBY STATE") \ SENSE_CODE(0x4, 0xc, "LOGICAL UNIT NOT ACCESSIBLE, TARGET PORT IN UNAVAILABLE STATE") \ SENSE_CODE(0x4, 0xd, "LOGICAL UNIT NOT READY, STRUCTURE CHECK REQUIRED") \ SENSE_CODE(0x4, 0xe, "LOGICAL UNIT NOT READY, SECURITY SESSION IN PROGRESS") \ SENSE_CODE(0x4, 0x10, "LOGICAL UNIT NOT READY, AUXILIARY MEMORY NOT ACCESSIBLE") \ SENSE_CODE(0x4, 0x11, "LOGICAL UNIT NOT READY, NOTIFY (ENABLE SPINUP) REQUIRED") \ SENSE_CODE(0x4, 0x12, "LOGICAL UNIT NOT READY, OFFLINE") \ SENSE_CODE(0x4, 0x13, "LOGICAL UNIT NOT READY, SA CREATION IN PROGRESS") \ SENSE_CODE(0x4, 0x14, "LOGICAL UNIT NOT READY, SPACE ALLOCATION IN PROGRESS") \ SENSE_CODE(0x4, 0x15, "LOGICAL UNIT NOT READY, ROBOTICS DISABLED") \ SENSE_CODE(0x4, 0x16, "LOGICAL UNIT NOT READY, CONFIGURATION REQUIRED") \ SENSE_CODE(0x4, 0x17, "LOGICAL UNIT NOT READY, CALIBRATION REQUIRED") \ SENSE_CODE(0x4, 0x18, "LOGICAL UNIT NOT READY, A DOOR IS OPEN") \ SENSE_CODE(0x4, 0x19, "LOGICAL UNIT NOT READY, OPERATING IN SEQUENTIAL MODE") \ SENSE_CODE(0x4, 0x1a, "LOGICAL UNIT NOT READY, START STOP UNIT COMMAND IN PROGRESS") \ SENSE_CODE(0x4, 0x1b, "LOGICAL UNIT NOT READY, SANITIZE IN PROGRESS") \ SENSE_CODE(0x4, 0x1c, "LOGICAL UNIT NOT READY, ADDITIONAL POWER USE NOT YET GRANTED") \ SENSE_CODE(0x4, 0x1d, "LOGICAL UNIT NOT READY, CONFIGURATION IN PROGRESS") \ SENSE_CODE(0x4, 0x1e, "LOGICAL UNIT NOT READY, MICROCODE ACTIVATION REQUIRED") \ SENSE_CODE(0x4, 0x1f, "LOGICAL UNIT NOT READY, MICROCODE DOWNLOAD REQUIRED") \ SENSE_CODE(0x4, 0x20, "LOGICAL UNIT NOT READY, LOGICAL UNIT RESET REQUIRED") \ SENSE_CODE(0x4, 0x21, "LOGICAL UNIT NOT READY, HARD RESET REQUIRED") \ SENSE_CODE(0x4, 0x22, "LOGICAL UNIT NOT READY, POWER CYCLE REQUIRED") \ SENSE_CODE(0x5, 0x0, "LOGICAL UNIT DOES NOT RESPOND TO SELECTION") \ SENSE_CODE(0x6, 0x0, "NO REFERENCE POSITION FOUND") \ SENSE_CODE(0x7, 0x0, "MULTIPLE PERIPHERAL DEVICES SELECTED") \ SENSE_CODE(0x8, 0x0, "LOGICAL UNIT COMMUNICATION FAILURE") \ SENSE_CODE(0x8, 0x1, "LOGICAL UNIT COMMUNICATION TIME-OUT") \ SENSE_CODE(0x8, 0x2, "LOGICAL UNIT COMMUNICATION PARITY ERROR") \ SENSE_CODE(0x8, 0x3, "LOGICAL UNIT COMMUNICATION CRC ERROR (ULTRA-DMA/32)") \ SENSE_CODE(0x8, 0x4, "UNREACHABLE COPY TARGET") \ SENSE_CODE(0x9, 0x0, "TRACK FOLLOWING ERROR") \ SENSE_CODE(0x9, 0x1, "TRACKING SERVO FAILURE") \ SENSE_CODE(0x9, 0x2, "FOCUS SERVO FAILURE") \ SENSE_CODE(0x9, 0x3, "SPINDLE SERVO FAILURE") \ SENSE_CODE(0x9, 0x4, "HEAD SELECT FAULT") \ SENSE_CODE(0x9, 0x5, "VIBRATION INDUCED TRACKING ERROR") \ SENSE_CODE(0xa, 0x0, "ERROR LOG OVERFLOW") \ SENSE_CODE(0xb, 0x0, "WARNING") \ SENSE_CODE(0xb, 0x1, "WARNING - SPECIFIED TEMPERATURE EXCEEDED") \ SENSE_CODE(0xb, 0x2, "WARNING - ENCLOSURE DEGRADED") \ SENSE_CODE(0xb, 0x3, "WARNING - BACKGROUND SELF-TEST FAILED") \ SENSE_CODE(0xb, 0x4, "WARNING - BACKGROUND PRE-SCAN DETECTED MEDIUM ERROR") \ SENSE_CODE(0xb, 0x5, "WARNING - BACKGROUND MEDIUM SCAN DETECTED MEDIUM ERROR") \ SENSE_CODE(0xb, 0x6, "WARNING - NON-VOLATILE CACHE NOW VOLATILE") \ SENSE_CODE(0xb, 0x7, "WARNING - DEGRADED POWER TO NON-VOLATILE CACHE") \ SENSE_CODE(0xb, 0x8, "WARNING - POWER LOSS EXPECTED") \ SENSE_CODE(0xb, 0x9, "WARNING - DEVICE STATISTICS NOTIFICATION ACTIVE") \ SENSE_CODE(0xb, 0xa, "WARNING - HIGH CRITICAL TEMPERATURE LIMIT EXCEEDED") \ SENSE_CODE(0xb, 0xb, "WARNING - LOW CRITICAL TEMPERATURE LIMIT EXCEEDED") \ SENSE_CODE(0xb, 0xc, "WARNING - HIGH OPERATING TEMPERATURE LIMIT EXCEEDED") \ SENSE_CODE(0xb, 0xd, "WARNING - LOW OPERATING TEMPERATURE LIMIT EXCEEDED") \ SENSE_CODE(0xb, 0xe, "WARNING - HIGH CRITICAL HUMIDITY LIMIT EXCEEDED") \ SENSE_CODE(0xb, 0xf, "WARNING - LOW CRITICAL HUMIDITY LIMIT EXCEEDED") \ SENSE_CODE(0xb, 0x10, "WARNING - HIGH OPERATING HUMIDITY LIMIT EXCEEDED") \ SENSE_CODE(0xb, 0x11, "WARNING - LOW OPERATING HUMIDITY LIMIT EXCEEDED") \ SENSE_CODE(0xc, 0x0, "WRITE ERROR") \ SENSE_CODE(0xc, 0x1, "WRITE ERROR - RECOVERED WITH AUTO REALLOCATION") \ SENSE_CODE(0xc, 0x2, "WRITE ERROR - AUTO REALLOCATION FAILED") \ SENSE_CODE(0xc, 0x3, "WRITE ERROR - RECOMMEND REASSIGNMENT") \ SENSE_CODE(0xc, 0x4, "COMPRESSION CHECK MISCOMPARE ERROR") \ SENSE_CODE(0xc, 0x5, "DATA EXPANSION OCCURRED DURING COMPRESSION") \ SENSE_CODE(0xc, 0x6, "BLOCK NOT COMPRESSIBLE") \ SENSE_CODE(0xc, 0x7, "WRITE ERROR - RECOVERY NEEDED") \ SENSE_CODE(0xc, 0x8, "WRITE ERROR - RECOVERY FAILED") \ SENSE_CODE(0xc, 0x9, "WRITE ERROR - LOSS OF STREAMING") \ SENSE_CODE(0xc, 0xa, "WRITE ERROR - PADDING BLOCKS ADDED") \ SENSE_CODE(0xc, 0xb, "AUXILIARY MEMORY WRITE ERROR") \ SENSE_CODE(0xc, 0xc, "WRITE ERROR - UNEXPECTED UNSOLICITED DATA") \ SENSE_CODE(0xc, 0xd, "WRITE ERROR - NOT ENOUGH UNSOLICITED DATA") \ SENSE_CODE(0xc, 0xe, "MULTIPLE WRITE ERRORS") \ SENSE_CODE(0xc, 0xf, "DEFECTS IN ERROR WINDOW") \ SENSE_CODE(0xc, 0x10, "INCOMPLETE MULTIPLE ATOMIC WRITE OPERATIONS") \ SENSE_CODE(0xd, 0x0, "ERROR DETECTED BY THIRD PARTY TEMPORARY INITIATOR") \ SENSE_CODE(0xd, 0x1, "THIRD PARTY DEVICE FAILURE") \ SENSE_CODE(0xd, 0x2, "COPY TARGET DEVICE NOT REACHABLE") \ SENSE_CODE(0xd, 0x3, "INCORRECT COPY TARGET DEVICE TYPE") \ SENSE_CODE(0xd, 0x4, "COPY TARGET DEVICE DATA UNDERRUN") \ SENSE_CODE(0xd, 0x5, "COPY TARGET DEVICE DATA OVERRUN") \ SENSE_CODE(0xe, 0x0, "INVALID INFORMATION UNIT") \ SENSE_CODE(0xe, 0x1, "INFORMATION UNIT TOO SHORT") \ SENSE_CODE(0xe, 0x2, "INFORMATION UNIT TOO LONG") \ SENSE_CODE(0xe, 0x3, "INVALID FIELD IN COMMAND INFORMATION UNIT") \ SENSE_CODE(0x10, 0x0, "ID CRC OR ECC ERROR") \ SENSE_CODE(0x10, 0x1, "LOGICAL BLOCK GUARD CHECK FAILED") \ SENSE_CODE(0x10, 0x2, "LOGICAL BLOCK APPLICATION TAG CHECK FAILED") \ SENSE_CODE(0x10, 0x3, "LOGICAL BLOCK REFERENCE TAG CHECK FAILED") \ SENSE_CODE(0x10, 0x4, "LOGICAL BLOCK PROTECTION ERROR ON RECOVER BUFFERED DATA") \ SENSE_CODE(0x10, 0x5, "LOGICAL BLOCK PROTECTION METHOD ERROR") \ SENSE_CODE(0x11, 0x0, "UNRECOVERED READ ERROR") \ SENSE_CODE(0x11, 0x1, "READ RETRIES EXHAUSTED") \ SENSE_CODE(0x11, 0x2, "ERROR TOO LONG TO CORRECT") \ SENSE_CODE(0x11, 0x3, "MULTIPLE READ ERRORS") \ SENSE_CODE(0x11, 0x4, "UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED") \ SENSE_CODE(0x11, 0x5, "L-EC UNCORRECTABLE ERROR") \ SENSE_CODE(0x11, 0x6, "CIRC UNRECOVERED ERROR") \ SENSE_CODE(0x11, 0x7, "DATA RE-SYNCHRONIZATION ERROR") \ SENSE_CODE(0x11, 0x8, "INCOMPLETE BLOCK READ") \ SENSE_CODE(0x11, 0x9, "NO GAP FOUND") \ SENSE_CODE(0x11, 0xa, "MISCORRECTED ERROR") \ SENSE_CODE(0x11, 0xb, "UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT") \ SENSE_CODE(0x11, 0xc, "UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA") \ SENSE_CODE(0x11, 0xd, "DE-COMPRESSION CRC ERROR") \ SENSE_CODE(0x11, 0xe, "CANNOT DECOMPRESS USING DECLARED ALGORITHM") \ SENSE_CODE(0x11, 0xf, "ERROR READING UPC/EAN NUMBER") \ SENSE_CODE(0x11, 0x10, "ERROR READING ISRC NUMBER") \ SENSE_CODE(0x11, 0x11, "READ ERROR - LOSS OF STREAMING") \ SENSE_CODE(0x11, 0x12, "AUXILIARY MEMORY READ ERROR") \ SENSE_CODE(0x11, 0x13, "READ ERROR - FAILED RETRANSMISSION REQUEST") \ SENSE_CODE(0x11, 0x14, "READ ERROR - LBA MARKED BAD BY APPLICATION CLIENT") \ SENSE_CODE(0x11, 0x15, "WRITE AFTER SANITIZE REQUIRED") \ SENSE_CODE(0x12, 0x0, "ADDRESS MARK NOT FOUND FOR ID FIELD") \ SENSE_CODE(0x13, 0x0, "ADDRESS MARK NOT FOUND FOR DATA FIELD") \ SENSE_CODE(0x14, 0x0, "RECORDED ENTITY NOT FOUND") \ SENSE_CODE(0x14, 0x1, "RECORD NOT FOUND") \ SENSE_CODE(0x14, 0x2, "FILEMARK OR SETMARK NOT FOUND") \ SENSE_CODE(0x14, 0x3, "END-OF-DATA NOT FOUND") \ SENSE_CODE(0x14, 0x4, "BLOCK SEQUENCE ERROR") \ SENSE_CODE(0x14, 0x5, "RECORD NOT FOUND - RECOMMEND REASSIGNMENT") \ SENSE_CODE(0x14, 0x6, "RECORD NOT FOUND - DATA AUTO-REALLOCATED") \ SENSE_CODE(0x14, 0x7, "LOCATE OPERATION FAILURE") \ SENSE_CODE(0x15, 0x0, "RANDOM POSITIONING ERROR") \ SENSE_CODE(0x15, 0x1, "MECHANICAL POSITIONING ERROR") \ SENSE_CODE(0x15, 0x2, "POSITIONING ERROR DETECTED BY READ OF MEDIUM") \ SENSE_CODE(0x16, 0x0, "DATA SYNCHRONIZATION MARK ERROR") \ SENSE_CODE(0x16, 0x1, "DATA SYNC ERROR - DATA REWRITTEN") \ SENSE_CODE(0x16, 0x2, "DATA SYNC ERROR - RECOMMEND REWRITE") \ SENSE_CODE(0x16, 0x3, "DATA SYNC ERROR - DATA AUTO-REALLOCATED") \ SENSE_CODE(0x16, 0x4, "DATA SYNC ERROR - RECOMMEND REASSIGNMENT") \ SENSE_CODE(0x17, 0x0, "RECOVERED DATA WITH NO ERROR CORRECTION APPLIED") \ SENSE_CODE(0x17, 0x1, "RECOVERED DATA WITH RETRIES") \ SENSE_CODE(0x17, 0x2, "RECOVERED DATA WITH POSITIVE HEAD OFFSET") \ SENSE_CODE(0x17, 0x3, "RECOVERED DATA WITH NEGATIVE HEAD OFFSET") \ SENSE_CODE(0x17, 0x4, "RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED") \ SENSE_CODE(0x17, 0x5, "RECOVERED DATA USING PREVIOUS SECTOR ID") \ SENSE_CODE(0x17, 0x6, "RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED") \ SENSE_CODE(0x17, 0x7, "RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT") \ SENSE_CODE(0x17, 0x8, "RECOVERED DATA WITHOUT ECC - RECOMMEND REWRITE") \ SENSE_CODE(0x17, 0x9, "RECOVERED DATA WITHOUT ECC - DATA REWRITTEN") \ SENSE_CODE(0x18, 0x0, "RECOVERED DATA WITH ERROR CORRECTION APPLIED") \ SENSE_CODE(0x18, 0x1, "RECOVERED DATA WITH ERROR CORR. & RETRIES APPLIED") \ SENSE_CODE(0x18, 0x2, "RECOVERED DATA - DATA AUTO-REALLOCATED") \ SENSE_CODE(0x18, 0x3, "RECOVERED DATA WITH CIRC") \ SENSE_CODE(0x18, 0x4, "RECOVERED DATA WITH L-EC") \ SENSE_CODE(0x18, 0x5, "RECOVERED DATA - RECOMMEND REASSIGNMENT") \ SENSE_CODE(0x18, 0x6, "RECOVERED DATA - RECOMMEND REWRITE") \ SENSE_CODE(0x18, 0x7, "RECOVERED DATA WITH ECC - DATA REWRITTEN") \ SENSE_CODE(0x18, 0x8, "RECOVERED DATA WITH LINKING") \ SENSE_CODE(0x19, 0x0, "DEFECT LIST ERROR") \ SENSE_CODE(0x19, 0x1, "DEFECT LIST NOT AVAILABLE") \ SENSE_CODE(0x19, 0x2, "DEFECT LIST ERROR IN PRIMARY LIST") \ SENSE_CODE(0x19, 0x3, "DEFECT LIST ERROR IN GROWN LIST") \ SENSE_CODE(0x1a, 0x0, "PARAMETER LIST LENGTH ERROR") \ SENSE_CODE(0x1b, 0x0, "SYNCHRONOUS DATA TRANSFER ERROR") \ SENSE_CODE(0x1c, 0x0, "DEFECT LIST NOT FOUND") \ SENSE_CODE(0x1c, 0x1, "PRIMARY DEFECT LIST NOT FOUND") \ SENSE_CODE(0x1c, 0x2, "GROWN DEFECT LIST NOT FOUND") \ SENSE_CODE(0x1d, 0x0, "MISCOMPARE DURING VERIFY OPERATION") \ SENSE_CODE(0x1d, 0x1, "MISCOMPARE VERIFY OF UNMAPPED LBA") \ SENSE_CODE(0x1e, 0x0, "RECOVERED ID WITH ECC CORRECTION") \ SENSE_CODE(0x1f, 0x0, "PARTIAL DEFECT LIST TRANSFER") \ SENSE_CODE(0x20, 0x0, "INVALID COMMAND OPERATION CODE") \ SENSE_CODE(0x20, 0x1, "ACCESS DENIED - INITIATOR PENDING-ENROLLED") \ SENSE_CODE(0x20, 0x2, "ACCESS DENIED - NO ACCESS RIGHTS") \ SENSE_CODE(0x20, 0x3, "ACCESS DENIED - INVALID MGMT ID KEY") \ SENSE_CODE(0x20, 0x4, "ILLEGAL COMMAND WHILE IN WRITE CAPABLE STATE") \ SENSE_CODE(0x20, 0x5, "Obsolete") \ SENSE_CODE(0x20, 0x6, "ILLEGAL COMMAND WHILE IN EXPLICIT ADDRESS MODE") \ SENSE_CODE(0x20, 0x7, "ILLEGAL COMMAND WHILE IN IMPLICIT ADDRESS MODE") \ SENSE_CODE(0x20, 0x8, "ACCESS DENIED - ENROLLMENT CONFLICT") \ SENSE_CODE(0x20, 0x9, "ACCESS DENIED - INVALID LU IDENTIFIER") \ SENSE_CODE(0x20, 0xa, "ACCESS DENIED - INVALID PROXY TOKEN") \ SENSE_CODE(0x20, 0xb, "ACCESS DENIED - ACL LUN CONFLICT") \ SENSE_CODE(0x20, 0xc, "ILLEGAL COMMAND WHEN NOT IN APPEND-ONLY MODE") \ SENSE_CODE(0x21, 0x0, "LOGICAL BLOCK ADDRESS OUT OF RANGE") \ SENSE_CODE(0x21, 0x1, "INVALID ELEMENT ADDRESS") \ SENSE_CODE(0x21, 0x2, "INVALID ADDRESS FOR WRITE") \ SENSE_CODE(0x21, 0x3, "INVALID WRITE CROSSING LAYER JUMP") \ SENSE_CODE(0x21, 0x4, "UNALIGNED WRITE COMMAND") \ SENSE_CODE(0x21, 0x5, "WRITE BOUNDARY VIOLATION") \ SENSE_CODE(0x21, 0x6, "ATTEMPT TO READ INVALID DATA") \ SENSE_CODE(0x21, 0x7, "READ BOUNDARY VIOLATION") \ SENSE_CODE(0x22, 0x0, "ILLEGAL FUNCTION (USE 20 00, 24 00, OR 26 00)") \ SENSE_CODE(0x23, 0x0, "INVALID TOKEN OPERATION, CAUSE NOT REPORTABLE") \ SENSE_CODE(0x23, 0x1, "INVALID TOKEN OPERATION, UNSUPPORTED TOKEN TYPE") \ SENSE_CODE(0x23, 0x2, "INVALID TOKEN OPERATION, REMOTE TOKEN USAGE NOT SUPPORTED") \ SENSE_CODE(0x23, 0x3, "INVALID TOKEN OPERATION, REMOTE ROD TOKEN CREATION NOT SUPPORTED") \ SENSE_CODE(0x23, 0x4, "INVALID TOKEN OPERATION, TOKEN UNKNOWN") \ SENSE_CODE(0x23, 0x5, "INVALID TOKEN OPERATION, TOKEN CORRUPT") \ SENSE_CODE(0x23, 0x6, "INVALID TOKEN OPERATION, TOKEN REVOKED") \ SENSE_CODE(0x23, 0x7, "INVALID TOKEN OPERATION, TOKEN EXPIRED") \ SENSE_CODE(0x23, 0x8, "INVALID TOKEN OPERATION, TOKEN CANCELLED") \ SENSE_CODE(0x23, 0x9, "INVALID TOKEN OPERATION, TOKEN DELETED") \ SENSE_CODE(0x23, 0xa, "INVALID TOKEN OPERATION, INVALID TOKEN LENGTH") \ SENSE_CODE(0x24, 0x0, "INVALID FIELD IN CDB") \ SENSE_CODE(0x24, 0x1, "CDB DECRYPTION ERROR") \ SENSE_CODE(0x24, 0x2, "Obsolete") \ SENSE_CODE(0x24, 0x3, "Obsolete") \ SENSE_CODE(0x24, 0x4, "SECURITY AUDIT VALUE FROZEN") \ SENSE_CODE(0x24, 0x5, "SECURITY WORKING KEY FROZEN") \ SENSE_CODE(0x24, 0x6, "NONCE NOT UNIQUE") \ SENSE_CODE(0x24, 0x7, "NONCE TIMESTAMP OUT OF RANGE") \ SENSE_CODE(0x24, 0x8, "INVALID XCDB") \ SENSE_CODE(0x25, 0x0, "LOGICAL UNIT NOT SUPPORTED") \ SENSE_CODE(0x26, 0x0, "INVALID FIELD IN PARAMETER LIST") \ SENSE_CODE(0x26, 0x1, "PARAMETER NOT SUPPORTED") \ SENSE_CODE(0x26, 0x2, "PARAMETER VALUE INVALID") \ SENSE_CODE(0x26, 0x3, "THRESHOLD PARAMETERS NOT SUPPORTED") \ SENSE_CODE(0x26, 0x4, "INVALID RELEASE OF PERSISTENT RESERVATION") \ SENSE_CODE(0x26, 0x5, "DATA DECRYPTION ERROR") \ SENSE_CODE(0x26, 0x6, "TOO MANY TARGET DESCRIPTORS") \ SENSE_CODE(0x26, 0x7, "UNSUPPORTED TARGET DESCRIPTOR TYPE CODE") \ SENSE_CODE(0x26, 0x8, "TOO MANY SEGMENT DESCRIPTORS") \ SENSE_CODE(0x26, 0x9, "UNSUPPORTED SEGMENT DESCRIPTOR TYPE CODE") \ SENSE_CODE(0x26, 0xa, "UNEXPECTED INEXACT SEGMENT") \ SENSE_CODE(0x26, 0xb, "INLINE DATA LENGTH EXCEEDED") \ SENSE_CODE(0x26, 0xc, "INVALID OPERATION FOR COPY SOURCE OR DESTINATION") \ SENSE_CODE(0x26, 0xd, "COPY SEGMENT GRANULARITY VIOLATION") \ SENSE_CODE(0x26, 0xe, "INVALID PARAMETER WHILE PORT IS ENABLED") \ SENSE_CODE(0x26, 0xf, "INVALID DATA-OUT BUFFER INTEGRITY CHECK VALUE") \ SENSE_CODE(0x26, 0x10, "DATA DECRYPTION KEY FAIL LIMIT REACHED") \ SENSE_CODE(0x26, 0x11, "INCOMPLETE KEY-ASSOCIATED DATA SET") \ SENSE_CODE(0x26, 0x12, "VENDOR SPECIFIC KEY REFERENCE NOT FOUND") \ SENSE_CODE(0x26, 0x13, "APPLICATION TAG MODE PAGE IS INVALID") \ SENSE_CODE(0x27, 0x0, "WRITE PROTECTED") \ SENSE_CODE(0x27, 0x1, "HARDWARE WRITE PROTECTED") \ SENSE_CODE(0x27, 0x2, "LOGICAL UNIT SOFTWARE WRITE PROTECTED") \ SENSE_CODE(0x27, 0x3, "ASSOCIATED WRITE PROTECT") \ SENSE_CODE(0x27, 0x4, "PERSISTENT WRITE PROTECT") \ SENSE_CODE(0x27, 0x5, "PERMANENT WRITE PROTECT") \ SENSE_CODE(0x27, 0x6, "CONDITIONAL WRITE PROTECT") \ SENSE_CODE(0x27, 0x7, "SPACE ALLOCATION FAILED WRITE PROTECT") \ SENSE_CODE(0x27, 0x8, "ZONE IS READ ONLY") \ SENSE_CODE(0x28, 0x0, "NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED") \ SENSE_CODE(0x28, 0x1, "IMPORT OR EXPORT ELEMENT ACCESSED") \ SENSE_CODE(0x28, 0x2, "FORMAT-LAYER MAY HAVE CHANGED") \ SENSE_CODE(0x28, 0x3, "IMPORT/EXPORT ELEMENT ACCESSED, MEDIUM CHANGED") \ SENSE_CODE(0x29, 0x0, "POWER ON, RESET, OR BUS DEVICE RESET OCCURRED") \ SENSE_CODE(0x29, 0x1, "POWER ON OCCURRED") \ SENSE_CODE(0x29, 0x2, "SCSI BUS RESET OCCURRED") \ SENSE_CODE(0x29, 0x3, "BUS DEVICE RESET FUNCTION OCCURRED") \ SENSE_CODE(0x29, 0x4, "DEVICE INTERNAL RESET") \ SENSE_CODE(0x29, 0x5, "TRANSCEIVER MODE CHANGED TO SINGLE-ENDED") \ SENSE_CODE(0x29, 0x6, "TRANSCEIVER MODE CHANGED TO LVD") \ SENSE_CODE(0x29, 0x7, "I_T NEXUS LOSS OCCURRED") \ SENSE_CODE(0x2a, 0x0, "PARAMETERS CHANGED") \ SENSE_CODE(0x2a, 0x1, "MODE PARAMETERS CHANGED") \ SENSE_CODE(0x2a, 0x2, "LOG PARAMETERS CHANGED") \ SENSE_CODE(0x2a, 0x3, "RESERVATIONS PREEMPTED") \ SENSE_CODE(0x2a, 0x4, "RESERVATIONS RELEASED") \ SENSE_CODE(0x2a, 0x5, "REGISTRATIONS PREEMPTED") \ SENSE_CODE(0x2a, 0x6, "ASYMMETRIC ACCESS STATE CHANGED") \ SENSE_CODE(0x2a, 0x7, "IMPLICIT ASYMMETRIC ACCESS STATE TRANSITION FAILED") \ SENSE_CODE(0x2a, 0x8, "PRIORITY CHANGED") \ SENSE_CODE(0x2a, 0x9, "CAPACITY DATA HAS CHANGED") \ SENSE_CODE(0x2a, 0xa, "ERROR HISTORY I_T NEXUS CLEARED") \ SENSE_CODE(0x2a, 0xb, "ERROR HISTORY SNAPSHOT RELEASED") \ SENSE_CODE(0x2a, 0xc, "ERROR RECOVERY ATTRIBUTES HAVE CHANGED") \ SENSE_CODE(0x2a, 0xd, "DATA ENCRYPTION CAPABILITIES CHANGED") \ SENSE_CODE(0x2a, 0x10, "TIMESTAMP CHANGED") \ SENSE_CODE(0x2a, 0x11, "DATA ENCRYPTION PARAMETERS CHANGED BY ANOTHER I_T NEXUS") \ SENSE_CODE(0x2a, 0x12, "DATA ENCRYPTION PARAMETERS CHANGED BY VENDOR SPECIFIC EVENT") \ SENSE_CODE(0x2a, 0x13, "DATA ENCRYPTION KEY INSTANCE COUNTER HAS CHANGED") \ SENSE_CODE(0x2a, 0x14, "SA CREATION CAPABILITIES DATA HAS CHANGED") \ SENSE_CODE(0x2a, 0x15, "MEDIUM REMOVAL PREVENTION PREEMPTED") \ SENSE_CODE(0x2b, 0x0, "COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT") \ SENSE_CODE(0x2c, 0x0, "COMMAND SEQUENCE ERROR") \ SENSE_CODE(0x2c, 0x1, "TOO MANY WINDOWS SPECIFIED") \ SENSE_CODE(0x2c, 0x2, "INVALID COMBINATION OF WINDOWS SPECIFIED") \ SENSE_CODE(0x2c, 0x3, "CURRENT PROGRAM AREA IS NOT EMPTY") \ SENSE_CODE(0x2c, 0x4, "CURRENT PROGRAM AREA IS EMPTY") \ SENSE_CODE(0x2c, 0x5, "ILLEGAL POWER CONDITION REQUEST") \ SENSE_CODE(0x2c, 0x6, "PERSISTENT PREVENT CONFLICT") \ SENSE_CODE(0x2c, 0x7, "PREVIOUS BUSY STATUS") \ SENSE_CODE(0x2c, 0x8, "PREVIOUS TASK SET FULL STATUS") \ SENSE_CODE(0x2c, 0x9, "PREVIOUS RESERVATION CONFLICT STATUS") \ SENSE_CODE(0x2c, 0xa, "PARTITION OR COLLECTION CONTAINS USER OBJECTS") \ SENSE_CODE(0x2c, 0xb, "NOT RESERVED") \ SENSE_CODE(0x2c, 0xc, "ORWRITE GENERATION DOES NOT MATCH") \ SENSE_CODE(0x2c, 0xd, "RESET WRITE POINTER NOT ALLOWED") \ SENSE_CODE(0x2c, 0xe, "ZONE IS OFFLINE") \ SENSE_CODE(0x2d, 0x0, "OVERWRITE ERROR ON UPDATE IN PLACE") \ SENSE_CODE(0x2e, 0x0, "INSUFFICIENT TIME FOR OPERATION") \ SENSE_CODE(0x2e, 0x1, "COMMAND TIMEOUT BEFORE PROCESSING") \ SENSE_CODE(0x2e, 0x2, "COMMAND TIMEOUT DURING PROCESSING") \ SENSE_CODE(0x2e, 0x3, "COMMAND TIMEOUT DURING PROCESSING DUE TO ERROR RECOVERY") \ SENSE_CODE(0x2f, 0x0, "COMMANDS CLEARED BY ANOTHER INITIATOR") \ SENSE_CODE(0x2f, 0x1, "COMMANDS CLEARED BY POWER LOSS NOTIFICATION") \ SENSE_CODE(0x2f, 0x2, "COMMANDS CLEARED BY DEVICE SERVER") \ SENSE_CODE(0x2f, 0x3, "SOME COMMANDS CLEARED BY QUEUING LAYER EVENT") \ SENSE_CODE(0x30, 0x0, "INCOMPATIBLE MEDIUM INSTALLED") \ SENSE_CODE(0x30, 0x1, "CANNOT READ MEDIUM - UNKNOWN FORMAT") \ SENSE_CODE(0x30, 0x2, "CANNOT READ MEDIUM - INCOMPATIBLE FORMAT") \ SENSE_CODE(0x30, 0x3, "CLEANING CARTRIDGE INSTALLED") \ SENSE_CODE(0x30, 0x4, "CANNOT WRITE MEDIUM - UNKNOWN FORMAT") \ SENSE_CODE(0x30, 0x5, "CANNOT WRITE MEDIUM - INCOMPATIBLE FORMAT") \ SENSE_CODE(0x30, 0x6, "CANNOT FORMAT MEDIUM - INCOMPATIBLE MEDIUM") \ SENSE_CODE(0x30, 0x7, "CLEANING FAILURE") \ SENSE_CODE(0x30, 0x8, "CANNOT WRITE - APPLICATION CODE MISMATCH") \ SENSE_CODE(0x30, 0x9, "CURRENT SESSION NOT FIXATED FOR APPEND") \ SENSE_CODE(0x30, 0xa, "CLEANING REQUEST REJECTED") \ SENSE_CODE(0x30, 0xc, "WORM MEDIUM - OVERWRITE ATTEMPTED") \ SENSE_CODE(0x30, 0xd, "WORM MEDIUM - INTEGRITY CHECK") \ SENSE_CODE(0x30, 0x10, "MEDIUM NOT FORMATTED") \ SENSE_CODE(0x30, 0x11, "INCOMPATIBLE VOLUME TYPE") \ SENSE_CODE(0x30, 0x12, "INCOMPATIBLE VOLUME QUALIFIER") \ SENSE_CODE(0x30, 0x13, "CLEANING VOLUME EXPIRED") \ SENSE_CODE(0x31, 0x0, "MEDIUM FORMAT CORRUPTED") \ SENSE_CODE(0x31, 0x1, "FORMAT COMMAND FAILED") \ SENSE_CODE(0x31, 0x2, "ZONED FORMATTING FAILED DUE TO SPARE LINKING") \ SENSE_CODE(0x31, 0x3, "SANITIZE COMMAND FAILED") \ SENSE_CODE(0x32, 0x0, "NO DEFECT SPARE LOCATION AVAILABLE") \ SENSE_CODE(0x32, 0x1, "DEFECT LIST UPDATE FAILURE") \ SENSE_CODE(0x33, 0x0, "TAPE LENGTH ERROR") \ SENSE_CODE(0x34, 0x0, "ENCLOSURE FAILURE") \ SENSE_CODE(0x35, 0x0, "ENCLOSURE SERVICES FAILURE") \ SENSE_CODE(0x35, 0x1, "UNSUPPORTED ENCLOSURE FUNCTION") \ SENSE_CODE(0x35, 0x2, "ENCLOSURE SERVICES UNAVAILABLE") \ SENSE_CODE(0x35, 0x3, "ENCLOSURE SERVICES TRANSFER FAILURE") \ SENSE_CODE(0x35, 0x4, "ENCLOSURE SERVICES TRANSFER REFUSED") \ SENSE_CODE(0x35, 0x5, "ENCLOSURE SERVICES CHECKSUM ERROR") \ SENSE_CODE(0x36, 0x0, "RIBBON, INK, OR TONER FAILURE") \ SENSE_CODE(0x37, 0x0, "ROUNDED PARAMETER") \ SENSE_CODE(0x38, 0x0, "EVENT STATUS NOTIFICATION") \ SENSE_CODE(0x38, 0x2, "ESN - POWER MANAGEMENT CLASS EVENT") \ SENSE_CODE(0x38, 0x4, "ESN - MEDIA CLASS EVENT") \ SENSE_CODE(0x38, 0x6, "ESN - DEVICE BUSY CLASS EVENT") \ SENSE_CODE(0x38, 0x7, "THIN PROVISIONING SOFT THRESHOLD REACHED") \ SENSE_CODE(0x39, 0x0, "SAVING PARAMETERS NOT SUPPORTED") \ SENSE_CODE(0x3a, 0x0, "MEDIUM NOT PRESENT") \ SENSE_CODE(0x3a, 0x1, "MEDIUM NOT PRESENT - TRAY CLOSED") \ SENSE_CODE(0x3a, 0x2, "MEDIUM NOT PRESENT - TRAY OPEN") \ SENSE_CODE(0x3a, 0x3, "MEDIUM NOT PRESENT - LOADABLE") \ SENSE_CODE(0x3a, 0x4, "MEDIUM NOT PRESENT - MEDIUM AUXILIARY MEMORY ACCESSIBLE") \ SENSE_CODE(0x3b, 0x0, "SEQUENTIAL POSITIONING ERROR") \ SENSE_CODE(0x3b, 0x1, "TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM") \ SENSE_CODE(0x3b, 0x2, "TAPE POSITION ERROR AT END-OF-MEDIUM") \ SENSE_CODE(0x3b, 0x3, "TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY") \ SENSE_CODE(0x3b, 0x4, "SLEW FAILURE") \ SENSE_CODE(0x3b, 0x5, "PAPER JAM") \ SENSE_CODE(0x3b, 0x6, "FAILED TO SENSE TOP-OF-FORM") \ SENSE_CODE(0x3b, 0x7, "FAILED TO SENSE BOTTOM-OF-FORM") \ SENSE_CODE(0x3b, 0x8, "REPOSITION ERROR") \ SENSE_CODE(0x3b, 0x9, "READ PAST END OF MEDIUM") \ SENSE_CODE(0x3b, 0xa, "READ PAST BEGINNING OF MEDIUM") \ SENSE_CODE(0x3b, 0xb, "POSITION PAST END OF MEDIUM") \ SENSE_CODE(0x3b, 0xc, "POSITION PAST BEGINNING OF MEDIUM") \ SENSE_CODE(0x3b, 0xd, "MEDIUM DESTINATION ELEMENT FULL") \ SENSE_CODE(0x3b, 0xe, "MEDIUM SOURCE ELEMENT EMPTY") \ SENSE_CODE(0x3b, 0xf, "END OF MEDIUM REACHED") \ SENSE_CODE(0x3b, 0x11, "MEDIUM MAGAZINE NOT ACCESSIBLE") \ SENSE_CODE(0x3b, 0x12, "MEDIUM MAGAZINE REMOVED") \ SENSE_CODE(0x3b, 0x13, "MEDIUM MAGAZINE INSERTED") \ SENSE_CODE(0x3b, 0x14, "MEDIUM MAGAZINE LOCKED") \ SENSE_CODE(0x3b, 0x15, "MEDIUM MAGAZINE UNLOCKED") \ SENSE_CODE(0x3b, 0x16, "MECHANICAL POSITIONING OR CHANGER ERROR") \ SENSE_CODE(0x3b, 0x17, "READ PAST END OF USER OBJECT") \ SENSE_CODE(0x3b, 0x18, "ELEMENT DISABLED") \ SENSE_CODE(0x3b, 0x19, "ELEMENT ENABLED") \ SENSE_CODE(0x3b, 0x1a, "DATA TRANSFER DEVICE REMOVED") \ SENSE_CODE(0x3b, 0x1b, "DATA TRANSFER DEVICE INSERTED") \ SENSE_CODE(0x3b, 0x1c, "TOO MANY LOGICAL OBJECTS ON PARTITION TO SUPPORT OPERATION") \ SENSE_CODE(0x3d, 0x0, "INVALID BITS IN IDENTIFY MESSAGE") \ SENSE_CODE(0x3e, 0x0, "LOGICAL UNIT HAS NOT SELF-CONFIGURED YET") \ SENSE_CODE(0x3e, 0x1, "LOGICAL UNIT FAILURE") \ SENSE_CODE(0x3e, 0x2, "TIMEOUT ON LOGICAL UNIT") \ SENSE_CODE(0x3e, 0x3, "LOGICAL UNIT FAILED SELF-TEST") \ SENSE_CODE(0x3e, 0x4, "LOGICAL UNIT UNABLE TO UPDATE SELF-TEST LOG") \ SENSE_CODE(0x3f, 0x0, "TARGET OPERATING CONDITIONS HAVE CHANGED") \ SENSE_CODE(0x3f, 0x1, "MICROCODE HAS BEEN CHANGED") \ SENSE_CODE(0x3f, 0x2, "CHANGED OPERATING DEFINITION") \ SENSE_CODE(0x3f, 0x3, "INQUIRY DATA HAS CHANGED") \ SENSE_CODE(0x3f, 0x4, "COMPONENT DEVICE ATTACHED") \ SENSE_CODE(0x3f, 0x5, "DEVICE IDENTIFIER CHANGED") \ SENSE_CODE(0x3f, 0x6, "REDUNDANCY GROUP CREATED OR MODIFIED") \ SENSE_CODE(0x3f, 0x7, "REDUNDANCY GROUP DELETED") \ SENSE_CODE(0x3f, 0x8, "SPARE CREATED OR MODIFIED") \ SENSE_CODE(0x3f, 0x9, "SPARE DELETED") \ SENSE_CODE(0x3f, 0xa, "VOLUME SET CREATED OR MODIFIED") \ SENSE_CODE(0x3f, 0xb, "VOLUME SET DELETED") \ SENSE_CODE(0x3f, 0xc, "VOLUME SET DEASSIGNED") \ SENSE_CODE(0x3f, 0xd, "VOLUME SET REASSIGNED") \ SENSE_CODE(0x3f, 0xe, "REPORTED LUNS DATA HAS CHANGED") \ SENSE_CODE(0x3f, 0xf, "ECHO BUFFER OVERWRITTEN") \ SENSE_CODE(0x3f, 0x10, "MEDIUM LOADABLE") \ SENSE_CODE(0x3f, 0x11, "MEDIUM AUXILIARY MEMORY ACCESSIBLE") \ SENSE_CODE(0x3f, 0x12, "iSCSI IP ADDRESS ADDED") \ SENSE_CODE(0x3f, 0x13, "iSCSI IP ADDRESS REMOVED") \ SENSE_CODE(0x3f, 0x14, "iSCSI IP ADDRESS CHANGED") \ SENSE_CODE(0x3f, 0x15, "INSPECT REFERRALS SENSE DESCRIPTORS") \ SENSE_CODE(0x3f, 0x16, "MICROCODE HAS BEEN CHANGED WITHOUT RESET") \ SENSE_CODE(0x40, 0x0, "RAM FAILURE (SHOULD USE 40 NN)") \ SENSE_CODE_KEYED(0x40, "DIAGNOSTIC FAILURE ON COMPONENT %u (80h-FFh)") \ SENSE_CODE(0x41, 0x0, "DATA PATH FAILURE (SHOULD USE 40 NN)") \ SENSE_CODE(0x42, 0x0, "POWER-ON OR SELF-TEST FAILURE (SHOULD USE 40 NN)") \ SENSE_CODE(0x43, 0x0, "MESSAGE ERROR") \ SENSE_CODE(0x44, 0x0, "INTERNAL TARGET FAILURE") \ SENSE_CODE(0x44, 0x1, "PERSISTENT RESERVATION INFORMATION LOST") \ SENSE_CODE(0x44, 0x71, "ATA DEVICE FAILED SET FEATURES") \ SENSE_CODE(0x45, 0x0, "SELECT OR RESELECT FAILURE") \ SENSE_CODE(0x46, 0x0, "UNSUCCESSFUL SOFT RESET") \ SENSE_CODE(0x47, 0x0, "SCSI PARITY ERROR") \ SENSE_CODE(0x47, 0x1, "DATA PHASE CRC ERROR DETECTED") \ SENSE_CODE(0x47, 0x2, "SCSI PARITY ERROR DETECTED DURING ST DATA PHASE") \ SENSE_CODE(0x47, 0x3, "INFORMATION UNIT iuCRC ERROR DETECTED") \ SENSE_CODE(0x47, 0x4, "ASYNCHRONOUS INFORMATION PROTECTION ERROR DETECTED") \ SENSE_CODE(0x47, 0x5, "PROTOCOL SERVICE CRC ERROR") \ SENSE_CODE(0x47, 0x6, "PHY TEST FUNCTION IN PROGRESS") \ SENSE_CODE(0x47, 0x7f, "SOME COMMANDS CLEARED BY ISCSI PROTOCOL EVENT") \ SENSE_CODE(0x48, 0x0, "INITIATOR DETECTED ERROR MESSAGE RECEIVED") \ SENSE_CODE(0x49, 0x0, "INVALID MESSAGE ERROR") \ SENSE_CODE(0x4a, 0x0, "COMMAND PHASE ERROR") \ SENSE_CODE(0x4b, 0x0, "DATA PHASE ERROR") \ SENSE_CODE(0x4b, 0x1, "INVALID TARGET PORT TRANSFER TAG RECEIVED") \ SENSE_CODE(0x4b, 0x2, "TOO MUCH WRITE DATA") \ SENSE_CODE(0x4b, 0x3, "ACK/NAK TIMEOUT") \ SENSE_CODE(0x4b, 0x4, "NAK RECEIVED") \ SENSE_CODE(0x4b, 0x5, "DATA OFFSET ERROR") \ SENSE_CODE(0x4b, 0x6, "INITIATOR RESPONSE TIMEOUT") \ SENSE_CODE(0x4b, 0x7, "CONNECTION LOST") \ SENSE_CODE(0x4b, 0x8, "DATA-IN BUFFER OVERFLOW - DATA BUFFER SIZE") \ SENSE_CODE(0x4b, 0x9, "DATA-IN BUFFER OVERFLOW - DATA BUFFER DESCRIPTOR AREA") \ SENSE_CODE(0x4b, 0xa, "DATA-IN BUFFER ERROR") \ SENSE_CODE(0x4b, 0xb, "DATA-OUT BUFFER OVERFLOW - DATA BUFFER SIZE") \ SENSE_CODE(0x4b, 0xc, "DATA-OUT BUFFER OVERFLOW - DATA BUFFER DESCRIPTOR AREA") \ SENSE_CODE(0x4b, 0xd, "DATA-OUT BUFFER ERROR") \ SENSE_CODE(0x4b, 0xe, "PCIE FABRIC ERROR") \ SENSE_CODE(0x4b, 0xf, "PCIE COMPLETION TIMEOUT") \ SENSE_CODE(0x4b, 0x10, "PCIE COMPLETER ABORT") \ SENSE_CODE(0x4b, 0x11, "PCIE POISONED TLP RECEIVED") \ SENSE_CODE(0x4b, 0x12, "PCIE ECRC CHECK FAILED") \ SENSE_CODE(0x4b, 0x13, "PCIE UNSUPPORTED REQUEST") \ SENSE_CODE(0x4b, 0x14, "PCIE ACS VIOLATION") \ SENSE_CODE(0x4b, 0x15, "PCIE TLP PREFIX BLOCKED") \ SENSE_CODE(0x4c, 0x0, "LOGICAL UNIT FAILED SELF-CONFIGURATION") \ SENSE_CODE_KEYED(0x4d, "TAGGED OVERLAPPED COMMANDS (%u = TASK TAG)") \ SENSE_CODE(0x4e, 0x0, "OVERLAPPED COMMANDS ATTEMPTED") \ SENSE_CODE(0x50, 0x0, "WRITE APPEND ERROR") \ SENSE_CODE(0x50, 0x1, "WRITE APPEND POSITION ERROR") \ SENSE_CODE(0x50, 0x2, "POSITION ERROR RELATED TO TIMING") \ SENSE_CODE(0x51, 0x0, "ERASE FAILURE") \ SENSE_CODE(0x51, 0x1, "ERASE FAILURE - INCOMPLETE ERASE OPERATION DETECTED") \ SENSE_CODE(0x52, 0x0, "CARTRIDGE FAULT") \ SENSE_CODE(0x53, 0x0, "MEDIA LOAD OR EJECT FAILED") \ SENSE_CODE(0x53, 0x1, "UNLOAD TAPE FAILURE") \ SENSE_CODE(0x53, 0x2, "MEDIUM REMOVAL PREVENTED") \ SENSE_CODE(0x53, 0x3, "MEDIUM REMOVAL PREVENTED BY DATA TRANSFER ELEMENT") \ SENSE_CODE(0x53, 0x4, "MEDIUM THREAD OR UNTHREAD FAILURE") \ SENSE_CODE(0x53, 0x5, "VOLUME IDENTIFIER INVALID") \ SENSE_CODE(0x53, 0x6, "VOLUME IDENTIFIER MISSING") \ SENSE_CODE(0x53, 0x7, "DUPLICATE VOLUME IDENTIFIER") \ SENSE_CODE(0x53, 0x8, "ELEMENT STATUS UNKNOWN") \ SENSE_CODE(0x53, 0x9, "DATA TRANSFER DEVICE ERROR - LOAD FAILED") \ SENSE_CODE(0x53, 0xa, "DATA TRANSFER DEVICE ERROR - UNLOAD FAILED") \ SENSE_CODE(0x53, 0xb, "DATA TRANSFER DEVICE ERROR - UNLOAD MISSING") \ SENSE_CODE(0x53, 0xc, "DATA TRANSFER DEVICE ERROR - EJECT FAILED") \ SENSE_CODE(0x53, 0xd, "DATA TRANSFER DEVICE ERROR - LIBRARY COMMUNICATION FAILED") \ SENSE_CODE(0x54, 0x0, "SCSI TO HOST SYSTEM INTERFACE FAILURE") \ SENSE_CODE(0x55, 0x0, "SYSTEM RESOURCE FAILURE") \ SENSE_CODE(0x55, 0x1, "SYSTEM BUFFER FULL") \ SENSE_CODE(0x55, 0x2, "INSUFFICIENT RESERVATION RESOURCES") \ SENSE_CODE(0x55, 0x3, "INSUFFICIENT RESOURCES") \ SENSE_CODE(0x55, 0x4, "INSUFFICIENT REGISTRATION RESOURCES") \ SENSE_CODE(0x55, 0x5, "INSUFFICIENT ACCESS CONTROL RESOURCES") \ SENSE_CODE(0x55, 0x6, "AUXILIARY MEMORY OUT OF SPACE") \ SENSE_CODE(0x55, 0x7, "QUOTA ERROR") \ SENSE_CODE(0x55, 0x8, "MAXIMUM NUMBER OF SUPPLEMENTAL DECRYPTION KEYS EXCEEDED") \ SENSE_CODE(0x55, 0x9, "MEDIUM AUXILIARY MEMORY NOT ACCESSIBLE") \ SENSE_CODE(0x55, 0xa, "DATA CURRENTLY UNAVAILABLE") \ SENSE_CODE(0x55, 0xb, "INSUFFICIENT POWER FOR OPERATION") \ SENSE_CODE(0x55, 0xc, "INSUFFICIENT RESOURCES TO CREATE ROD") \ SENSE_CODE(0x55, 0xd, "INSUFFICIENT RESOURCES TO CREATE ROD TOKEN") \ SENSE_CODE(0x55, 0xe, "INSUFFICIENT ZONE RESOURCES") \ SENSE_CODE(0x57, 0x0, "UNABLE TO RECOVER TABLE-OF-CONTENTS") \ SENSE_CODE(0x58, 0x0, "GENERATION DOES NOT EXIST") \ SENSE_CODE(0x59, 0x0, "UPDATED BLOCK READ") \ SENSE_CODE(0x5a, 0x0, "OPERATOR REQUEST OR STATE CHANGE INPUT") \ SENSE_CODE(0x5a, 0x1, "OPERATOR MEDIUM REMOVAL REQUEST") \ SENSE_CODE(0x5a, 0x2, "OPERATOR SELECTED WRITE PROTECT") \ SENSE_CODE(0x5a, 0x3, "OPERATOR SELECTED WRITE PERMIT") \ SENSE_CODE(0x5b, 0x0, "LOG EXCEPTION") \ SENSE_CODE(0x5b, 0x1, "THRESHOLD CONDITION MET") \ SENSE_CODE(0x5b, 0x2, "LOG COUNTER AT MAXIMUM") \ SENSE_CODE(0x5b, 0x3, "LOG LIST CODES EXHAUSTED") \ SENSE_CODE(0x5c, 0x0, "RPL STATUS CHANGE") \ SENSE_CODE(0x5c, 0x1, "SPINDLES SYNCHRONIZED") \ SENSE_CODE(0x5c, 0x2, "SPINDLES NOT SYNCHRONIZED") \ SENSE_CODE(0x5d, 0x0, "FAILURE PREDICTION THRESHOLD EXCEEDED") \ SENSE_CODE(0x5d, 0x1, "MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED") \ SENSE_CODE(0x5d, 0x2, "LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED") \ SENSE_CODE(0x5d, 0x3, "SPARE AREA EXHAUSTION PREDICTION THRESHOLD EXCEEDED") \ SENSE_CODE(0x5d, 0x10, "HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE") \ SENSE_CODE(0x5d, 0x11, "HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x12, "HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x13, "HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x14, "HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS") \ SENSE_CODE(0x5d, 0x15, "HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x16, "HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x17, "HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS") \ SENSE_CODE(0x5d, 0x18, "HARDWARE IMPENDING FAILURE CONTROLLER DETECTED") \ SENSE_CODE(0x5d, 0x19, "HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE") \ SENSE_CODE(0x5d, 0x1a, "HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE") \ SENSE_CODE(0x5d, 0x1b, "HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT") \ SENSE_CODE(0x5d, 0x1c, "HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT") \ SENSE_CODE(0x5d, 0x20, "CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE") \ SENSE_CODE(0x5d, 0x21, "CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x22, "CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x23, "CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x24, "CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS") \ SENSE_CODE(0x5d, 0x25, "CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x26, "CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x27, "CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS") \ SENSE_CODE(0x5d, 0x28, "CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED") \ SENSE_CODE(0x5d, 0x29, "CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE") \ SENSE_CODE(0x5d, 0x2a, "CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE") \ SENSE_CODE(0x5d, 0x2b, "CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT") \ SENSE_CODE(0x5d, 0x2c, "CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT") \ SENSE_CODE(0x5d, 0x30, "DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE") \ SENSE_CODE(0x5d, 0x31, "DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x32, "DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x33, "DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x34, "DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS") \ SENSE_CODE(0x5d, 0x35, "DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x36, "DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x37, "DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS") \ SENSE_CODE(0x5d, 0x38, "DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED") \ SENSE_CODE(0x5d, 0x39, "DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE") \ SENSE_CODE(0x5d, 0x3a, "DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE") \ SENSE_CODE(0x5d, 0x3b, "DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT") \ SENSE_CODE(0x5d, 0x3c, "DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT") \ SENSE_CODE(0x5d, 0x40, "SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE") \ SENSE_CODE(0x5d, 0x41, "SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x42, "SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x43, "SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x44, "SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS") \ SENSE_CODE(0x5d, 0x45, "SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x46, "SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x47, "SERVO IMPENDING FAILURE CHANNEL PARAMETRICS") \ SENSE_CODE(0x5d, 0x48, "SERVO IMPENDING FAILURE CONTROLLER DETECTED") \ SENSE_CODE(0x5d, 0x49, "SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE") \ SENSE_CODE(0x5d, 0x4a, "SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE") \ SENSE_CODE(0x5d, 0x4b, "SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT") \ SENSE_CODE(0x5d, 0x4c, "SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT") \ SENSE_CODE(0x5d, 0x50, "SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE") \ SENSE_CODE(0x5d, 0x51, "SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x52, "SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x53, "SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x54, "SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS") \ SENSE_CODE(0x5d, 0x55, "SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x56, "SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x57, "SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS") \ SENSE_CODE(0x5d, 0x58, "SPINDLE IMPENDING FAILURE CONTROLLER DETECTED") \ SENSE_CODE(0x5d, 0x59, "SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE") \ SENSE_CODE(0x5d, 0x5a, "SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE") \ SENSE_CODE(0x5d, 0x5b, "SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT") \ SENSE_CODE(0x5d, 0x5c, "SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT") \ SENSE_CODE(0x5d, 0x60, "FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE") \ SENSE_CODE(0x5d, 0x61, "FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x62, "FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x63, "FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH") \ SENSE_CODE(0x5d, 0x64, "FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS") \ SENSE_CODE(0x5d, 0x65, "FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x66, "FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH") \ SENSE_CODE(0x5d, 0x67, "FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS") \ SENSE_CODE(0x5d, 0x68, "FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED") \ SENSE_CODE(0x5d, 0x69, "FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE") \ SENSE_CODE(0x5d, 0x6a, "FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE") \ SENSE_CODE(0x5d, 0x6b, "FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT") \ SENSE_CODE(0x5d, 0x6c, "FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT") \ SENSE_CODE(0x5d, 0xff, "FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE)") \ SENSE_CODE(0x5e, 0x0, "LOW POWER CONDITION ON") \ SENSE_CODE(0x5e, 0x1, "IDLE CONDITION ACTIVATED BY TIMER") \ SENSE_CODE(0x5e, 0x2, "STANDBY CONDITION ACTIVATED BY TIMER") \ SENSE_CODE(0x5e, 0x3, "IDLE CONDITION ACTIVATED BY COMMAND") \ SENSE_CODE(0x5e, 0x4, "STANDBY CONDITION ACTIVATED BY COMMAND") \ SENSE_CODE(0x5e, 0x5, "IDLE_B CONDITION ACTIVATED BY TIMER") \ SENSE_CODE(0x5e, 0x6, "IDLE_B CONDITION ACTIVATED BY COMMAND") \ SENSE_CODE(0x5e, 0x7, "IDLE_C CONDITION ACTIVATED BY TIMER") \ SENSE_CODE(0x5e, 0x8, "IDLE_C CONDITION ACTIVATED BY COMMAND") \ SENSE_CODE(0x5e, 0x9, "STANDBY_Y CONDITION ACTIVATED BY TIMER") \ SENSE_CODE(0x5e, 0xa, "STANDBY_Y CONDITION ACTIVATED BY COMMAND") \ SENSE_CODE(0x5e, 0x41, "POWER STATE CHANGE TO ACTIVE") \ SENSE_CODE(0x5e, 0x42, "POWER STATE CHANGE TO IDLE") \ SENSE_CODE(0x5e, 0x43, "POWER STATE CHANGE TO STANDBY") \ SENSE_CODE(0x5e, 0x45, "POWER STATE CHANGE TO SLEEP") \ SENSE_CODE(0x5e, 0x47, "POWER STATE CHANGE TO DEVICE CONTROL") \ SENSE_CODE(0x60, 0x0, "LAMP FAILURE") \ SENSE_CODE(0x61, 0x0, "VIDEO ACQUISITION ERROR") \ SENSE_CODE(0x61, 0x1, "UNABLE TO ACQUIRE VIDEO") \ SENSE_CODE(0x61, 0x2, "OUT OF FOCUS") \ SENSE_CODE(0x62, 0x0, "SCAN HEAD POSITIONING ERROR") \ SENSE_CODE(0x63, 0x0, "END OF USER AREA ENCOUNTERED ON THIS TRACK") \ SENSE_CODE(0x63, 0x1, "PACKET DOES NOT FIT IN AVAILABLE SPACE") \ SENSE_CODE(0x64, 0x0, "ILLEGAL MODE FOR THIS TRACK") \ SENSE_CODE(0x64, 0x1, "INVALID PACKET SIZE") \ SENSE_CODE(0x65, 0x0, "VOLTAGE FAULT") \ SENSE_CODE(0x66, 0x0, "AUTOMATIC DOCUMENT FEEDER COVER UP") \ SENSE_CODE(0x66, 0x1, "AUTOMATIC DOCUMENT FEEDER LIFT UP") \ SENSE_CODE(0x66, 0x2, "DOCUMENT JAM IN AUTOMATIC DOCUMENT FEEDER") \ SENSE_CODE(0x66, 0x3, "DOCUMENT MISS FEED AUTOMATIC IN DOCUMENT FEEDER") \ SENSE_CODE(0x67, 0x0, "CONFIGURATION FAILURE") \ SENSE_CODE(0x67, 0x1, "CONFIGURATION OF INCAPABLE LOGICAL UNITS FAILED") \ SENSE_CODE(0x67, 0x2, "ADD LOGICAL UNIT FAILED") \ SENSE_CODE(0x67, 0x3, "MODIFICATION OF LOGICAL UNIT FAILED") \ SENSE_CODE(0x67, 0x4, "EXCHANGE OF LOGICAL UNIT FAILED") \ SENSE_CODE(0x67, 0x5, "REMOVE OF LOGICAL UNIT FAILED") \ SENSE_CODE(0x67, 0x6, "ATTACHMENT OF LOGICAL UNIT FAILED") \ SENSE_CODE(0x67, 0x7, "CREATION OF LOGICAL UNIT FAILED") \ SENSE_CODE(0x67, 0x8, "ASSIGN FAILURE OCCURRED") \ SENSE_CODE(0x67, 0x9, "MULTIPLY ASSIGNED LOGICAL UNIT") \ SENSE_CODE(0x67, 0xa, "SET TARGET PORT GROUPS COMMAND FAILED") \ SENSE_CODE(0x67, 0xb, "ATA DEVICE FEATURE NOT ENABLED") \ SENSE_CODE(0x68, 0x0, "LOGICAL UNIT NOT CONFIGURED") \ SENSE_CODE(0x68, 0x1, "SUBSIDIARY LOGICAL UNIT NOT CONFIGURED") \ SENSE_CODE(0x69, 0x0, "DATA LOSS ON LOGICAL UNIT") \ SENSE_CODE(0x69, 0x1, "MULTIPLE LOGICAL UNIT FAILURES") \ SENSE_CODE(0x69, 0x2, "PARITY/DATA MISMATCH") \ SENSE_CODE(0x6a, 0x0, "INFORMATIONAL, REFER TO LOG") \ SENSE_CODE(0x6b, 0x0, "STATE CHANGE HAS OCCURRED") \ SENSE_CODE(0x6b, 0x1, "REDUNDANCY LEVEL GOT BETTER") \ SENSE_CODE(0x6b, 0x2, "REDUNDANCY LEVEL GOT WORSE") \ SENSE_CODE(0x6c, 0x0, "REBUILD FAILURE OCCURRED") \ SENSE_CODE(0x6d, 0x0, "RECALCULATE FAILURE OCCURRED") \ SENSE_CODE(0x6e, 0x0, "COMMAND TO LOGICAL UNIT FAILED") \ SENSE_CODE(0x6f, 0x0, "COPY PROTECTION KEY EXCHANGE FAILURE - AUTHENTICATION FAILURE") \ SENSE_CODE(0x6f, 0x1, "COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT PRESENT") \ SENSE_CODE(0x6f, 0x2, "COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED") \ SENSE_CODE(0x6f, 0x3, "READ OF SCRAMBLED SECTOR WITHOUT AUTHENTICATION") \ SENSE_CODE(0x6f, 0x4, "MEDIA REGION CODE IS MISMATCHED TO LOGICAL UNIT REGION") \ SENSE_CODE(0x6f, 0x5, "DRIVE REGION MUST BE PERMANENT/REGION RESET COUNT ERROR") \ SENSE_CODE(0x6f, 0x6, "INSUFFICIENT BLOCK COUNT FOR BINDING NONCE RECORDING") \ SENSE_CODE(0x6f, 0x7, "CONFLICT IN BINDING NONCE RECORDING") \ SENSE_CODE_KEYED(0x70, "DECOMPRESSION EXCEPTION SHORT ALGORITHM ID OF %u") \ SENSE_CODE(0x71, 0x0, "DECOMPRESSION EXCEPTION LONG ALGORITHM ID") \ SENSE_CODE(0x72, 0x0, "SESSION FIXATION ERROR") \ SENSE_CODE(0x72, 0x1, "SESSION FIXATION ERROR WRITING LEAD-IN") \ SENSE_CODE(0x72, 0x2, "SESSION FIXATION ERROR WRITING LEAD-OUT") \ SENSE_CODE(0x72, 0x3, "SESSION FIXATION ERROR - INCOMPLETE TRACK IN SESSION") \ SENSE_CODE(0x72, 0x4, "EMPTY OR PARTIALLY WRITTEN RESERVED TRACK") \ SENSE_CODE(0x72, 0x5, "NO MORE TRACK RESERVATIONS ALLOWED") \ SENSE_CODE(0x72, 0x6, "RMZ EXTENSION IS NOT ALLOWED") \ SENSE_CODE(0x72, 0x7, "NO MORE TEST ZONE EXTENSIONS ARE ALLOWED") \ SENSE_CODE(0x73, 0x0, "CD CONTROL ERROR") \ SENSE_CODE(0x73, 0x1, "POWER CALIBRATION AREA ALMOST FULL") \ SENSE_CODE(0x73, 0x2, "POWER CALIBRATION AREA IS FULL") \ SENSE_CODE(0x73, 0x3, "POWER CALIBRATION AREA ERROR") \ SENSE_CODE(0x73, 0x4, "PROGRAM MEMORY AREA UPDATE FAILURE") \ SENSE_CODE(0x73, 0x5, "PROGRAM MEMORY AREA IS FULL") \ SENSE_CODE(0x73, 0x6, "RMA/PMA IS ALMOST FULL") \ SENSE_CODE(0x73, 0x10, "CURRENT POWER CALIBRATION AREA ALMOST FULL") \ SENSE_CODE(0x73, 0x11, "CURRENT POWER CALIBRATION AREA IS FULL") \ SENSE_CODE(0x73, 0x17, "RDZ IS FULL") \ SENSE_CODE(0x74, 0x0, "SECURITY ERROR") \ SENSE_CODE(0x74, 0x1, "UNABLE TO DECRYPT DATA") \ SENSE_CODE(0x74, 0x2, "UNENCRYPTED DATA ENCOUNTERED WHILE DECRYPTING") \ SENSE_CODE(0x74, 0x3, "INCORRECT DATA ENCRYPTION KEY") \ SENSE_CODE(0x74, 0x4, "CRYPTOGRAPHIC INTEGRITY VALIDATION FAILED") \ SENSE_CODE(0x74, 0x5, "ERROR DECRYPTING DATA") \ SENSE_CODE(0x74, 0x6, "UNKNOWN SIGNATURE VERIFICATION KEY") \ SENSE_CODE(0x74, 0x7, "ENCRYPTION PARAMETERS NOT USEABLE") \ SENSE_CODE(0x74, 0x8, "DIGITAL SIGNATURE VALIDATION FAILURE") \ SENSE_CODE(0x74, 0x9, "ENCRYPTION MODE MISMATCH ON READ") \ SENSE_CODE(0x74, 0xa, "ENCRYPTED BLOCK NOT RAW READ ENABLED") \ SENSE_CODE(0x74, 0xb, "INCORRECT ENCRYPTION PARAMETERS") \ SENSE_CODE(0x74, 0xc, "UNABLE TO DECRYPT PARAMETER LIST") \ SENSE_CODE(0x74, 0xd, "ENCRYPTION ALGORITHM DISABLED") \ SENSE_CODE(0x74, 0x10, "SA CREATION PARAMETER VALUE INVALID") \ SENSE_CODE(0x74, 0x11, "SA CREATION PARAMETER VALUE REJECTED") \ SENSE_CODE(0x74, 0x12, "INVALID SA USAGE") \ SENSE_CODE(0x74, 0x21, "DATA ENCRYPTION CONFIGURATION PREVENTED") \ SENSE_CODE(0x74, 0x30, "SA CREATION PARAMETER NOT SUPPORTED") \ SENSE_CODE(0x74, 0x40, "AUTHENTICATION FAILED") \ SENSE_CODE(0x74, 0x61, "EXTERNAL DATA ENCRYPTION KEY MANAGER ACCESS ERROR") \ SENSE_CODE(0x74, 0x62, "EXTERNAL DATA ENCRYPTION KEY MANAGER ERROR") \ SENSE_CODE(0x74, 0x63, "EXTERNAL DATA ENCRYPTION KEY NOT FOUND") \ SENSE_CODE(0x74, 0x64, "EXTERNAL DATA ENCRYPTION REQUEST NOT AUTHORIZED") \ SENSE_CODE(0x74, 0x6e, "EXTERNAL DATA ENCRYPTION CONTROL TIMEOUT") \ SENSE_CODE(0x74, 0x6f, "EXTERNAL DATA ENCRYPTION CONTROL ERROR") \ SENSE_CODE(0x74, 0x71, "LOGICAL UNIT ACCESS NOT AUTHORIZED") \ SENSE_CODE(0x74, 0x79, "SECURITY CONFLICT IN TRANSLATED DEVICE") \ #endif diskscan-0.21/libscsicmd/include/ata.h000066400000000000000000000200221456470715000177150ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_ATA_H #define LIBSCSICMD_ATA_H #include #include #include "scsicmd.h" typedef uint16_t ata_word_t; typedef uint32_t ata_longword_t; typedef uint64_t ata_qword_t; typedef enum passthrough_protocol_e { PT_PROTO_HARDWARE_RESET = 0, PT_PROTO_SOFTWARE_RESET = 1, PT_PROTO_NON_DATA = 3, PT_PROTO_PIO_DATA_IN = 4, PT_PROTO_PIO_DATA_OUT = 5, PT_PROTO_DMA = 6, PT_PROTO_DMA_QUEUED = 7, PT_PROTO_EXECUTE_DEVICE_DIAGNOSTIC = 8, PT_PROTO_DEVICE_RESET = 9, PT_PROTO_UDMA_DATA_IN = 10, PT_PROTO_UDMA_DATA_OUT = 11, PT_PROTO_FPDMA = 12, PT_PROTO_RETURN_RESPONSE_INFO = 15, } passthrough_protocol_e; typedef enum ata_passthrough_len_spec_e { ATA_PT_LEN_SPEC_NONE = 0, ATA_PT_LEN_SPEC_FEATURES = 1, ATA_PT_LEN_SPEC_SECTOR_COUNT = 2, ATA_PT_LEN_SPEC_TPSIU = 3, } ata_passthrough_len_spec_e; static inline ata_word_t ata_get_word(const unsigned char *buf, int word) { return (uint16_t)(buf[word*2+1])<<8 | buf[word*2]; } static inline uint16_t ata_get_bits(const unsigned char *buf, int word, int start_bit, int end_bit) { uint16_t val = ata_get_word(buf, word); uint16_t shift = start_bit; uint16_t mask = 0; switch (end_bit - start_bit + 1) { case 1: mask = 1; break; case 2: mask = 3; break; case 3: mask = 7; break; case 4: mask = 0xF; break; case 5: mask = 0x1F; break; case 6: mask = 0x3F; break; case 7: mask = 0x7F; break; case 8: mask = 0xFF; break; case 9: mask = 0x1FF; break; case 10: mask = 0x3FF; break; case 11: mask = 0x7FF; break; case 12: mask = 0xFFF; break; case 13: mask = 0x1FFF; break; case 14: mask = 0x3FFF; break; case 15: mask = 0x7FFF; break; case 16: mask = 0xFFFF; break; } return (val >> shift) & mask; } static inline bool ata_get_bit(const unsigned char *buf, int word, int bit) { return ata_get_bits(buf, word, bit, bit); } static inline char *ata_get_string(const unsigned char *buf, int word_start, int word_end, char *str) { int word; int i; /* Need to reverse the characters in the string as per "ATA string conventions" of ATA/ATAPI command set */ for (i = 0, word = word_start; word <= word_end; word++) { str[i++] = buf[word*2+1]; str[i++] = buf[word*2]; } str[i] = 0; return str; } static inline ata_longword_t ata_get_longword(const unsigned char *buf, int start_word) { ata_longword_t high = ata_get_word(buf, start_word+1); ata_longword_t low = ata_get_word(buf, start_word); ata_longword_t longword = high << 16 | low; return longword; } static inline ata_qword_t ata_get_qword(const unsigned char *buf, int start_word) { ata_qword_t low = ata_get_longword(buf, start_word); ata_qword_t high = ata_get_longword(buf, start_word+2); ata_qword_t qword = high << 32 | low; return qword; } bool ata_inquiry_checksum_verify(const unsigned char *buf, int buf_len); static inline unsigned char ata_passthrough_flags_2(int offline, int ck_cond, int direction_in, int transfer_block, ata_passthrough_len_spec_e len_spec) { return ((offline & 3) << 6) | ((ck_cond&1)<<5) | ((direction_in & 1) << 3) | ((transfer_block & 1) << 2) | (len_spec & 3); } static inline int cdb_ata_passthrough_12(unsigned char *cdb, uint8_t command, uint8_t feature, uint32_t lba, uint8_t sector_count, passthrough_protocol_e protocol, bool dir_in, int ck_cond) { cdb[0] = 0xA1; cdb[1] = protocol<<1; cdb[2] = ata_passthrough_flags_2(0, ck_cond, dir_in, 1, ATA_PT_LEN_SPEC_SECTOR_COUNT); cdb[3] = feature; cdb[4] = sector_count; cdb[5] = lba & 0xFF; cdb[6] = (lba >> 8) & 0xFF; cdb[7] = (lba >> 16) & 0xFF; cdb[8] = (lba >> 24) & 0x0F; // 28-bit addressing cdb[9] = command; cdb[10] = cdb[11] = 0; return 12; } static inline int cdb_ata_passthrough_16(unsigned char *cdb, uint8_t command, uint16_t feature, uint64_t lba, uint16_t sector_count, passthrough_protocol_e protocol, bool dir_in, int ck_cond, uint8_t device) { cdb[0] = 0x85; cdb[1] = protocol<<1 | 1; // Turn on EXTEND for 48-bit addressing cdb[2] = ata_passthrough_flags_2(0, ck_cond, dir_in, 1, ATA_PT_LEN_SPEC_SECTOR_COUNT); cdb[3] = (feature >> 8) & 0xFF; cdb[4] = feature & 0xFF; cdb[5] = (sector_count >> 8) & 0xFF; cdb[6] = sector_count & 0xFF; cdb[7] = (lba >> 24) & 0xFF; cdb[8] = lba & 0xFF; cdb[9] = (lba >> 32) & 0xFF; cdb[10] = (lba >> 8) & 0xFF; cdb[11] = (lba >> 40) & 0xFF; cdb[12] = (lba >> 16) & 0xFF; cdb[13] = device; cdb[14] = command; cdb[15] = 0; return 16; } static inline int cdb_ata_identify(unsigned char *cdb) { return cdb_ata_passthrough_12(cdb, 0xEC, 0x00, 0x0, 1, PT_PROTO_DMA, true, 0); } static inline int cdb_ata_identify_16(unsigned char *cdb) { return cdb_ata_passthrough_16(cdb, 0xEC, 0x00, 0x0, 1, PT_PROTO_DMA, true, 0, 0); } static inline int cdb_ata_smart_return_status(unsigned char *cdb) { return cdb_ata_passthrough_12(cdb, 0xB0, 0xDA, 0xC24F<<8, 1, PT_PROTO_DMA, true, 1); } bool ata_status_from_scsi_sense(unsigned char *sense, int sense_len, ata_status_t *status); static inline bool ata_smart_return_status_result(unsigned char *sense, int sense_len, bool *smart_ok) { ata_status_t status; if (!ata_status_from_scsi_sense(sense, sense_len, &status)) return false; if (status.lba >> 8 == 0xC24F) *smart_ok = true; else if (status.lba >> 8 == 0x2CF4) *smart_ok = false; else return false; return true; } static inline int cdb_ata_smart_read_data(unsigned char *cdb) { return cdb_ata_passthrough_12(cdb, 0xB0, 0xD0, 0xC24F<<8, 1, PT_PROTO_DMA, true, 0); } static inline int cdb_ata_smart_read_log(unsigned char *cdb, uint8_t log_addr, uint8_t num_pages) { return cdb_ata_passthrough_12(cdb, 0xB0, 0xD5, (0xC24F<<8) | log_addr, num_pages, PT_PROTO_PIO_DATA_IN, true, 0); } static inline int cdb_ata_smart_read_threshold(unsigned char *cdb) { return cdb_ata_passthrough_12(cdb, 0xB0, 0xD1, 0xC24F<<8, 1, PT_PROTO_DMA, true, 0); } static inline int cdb_ata_check_power_mode(unsigned char *cdb) { return cdb_ata_passthrough_12(cdb, 0xE5, 0, 0, 0, PT_PROTO_NON_DATA, true, 1); } static inline int cdb_ata_read_log_ext(unsigned char *cdb, uint16_t block_count, uint16_t page_number, uint8_t log_address) { uint64_t lba = ((page_number & 0xFF00) << 24) | ((page_number & 0xFF) << 8) | log_address; return cdb_ata_passthrough_16(cdb, 0x2F, 0, lba, block_count, PT_PROTO_PIO_DATA_IN, true, false, 0); } /* Parse ATA SMART READ DATA results */ #define MAX_SMART_ATTRS 30 typedef struct ata_smart_attr { uint8_t id; uint16_t status; uint8_t value; uint8_t min; uint8_t threshold; uint64_t raw; } ata_smart_attr_t; typedef struct ata_smart_thresh { uint8_t id; uint8_t threshold; } ata_smart_thresh_t; /** Calculate the page checksum for an ATA buffer, this is needed on ATA IDENTIFY DEVICE and in SMART commands. * We assume the buffer size is 512 always. */ static inline uint8_t ata_calc_checksum(const unsigned char *buf) { unsigned val = 0; int i; for (i = 0; i < 511; i++) val += buf[i]; return 0x100 - (val & 0xFF); // We want the complement } static inline bool ata_checksum_verify(const unsigned char *buf) { return ata_calc_checksum(buf) == buf[511]; } static inline uint8_t ata_get_ata_smart_read_data_checksum(const unsigned char *buf) { return buf[511]; } static inline bool ata_check_ata_smart_read_data_checksum(const unsigned char *buf) { return ata_checksum_verify(buf); } uint16_t ata_get_ata_smart_read_data_version(const unsigned char *buf); int ata_parse_ata_smart_read_data(const unsigned char *buf, ata_smart_attr_t *attrs, int max_attrs); int ata_parse_ata_smart_read_thresh(const unsigned char *buf, ata_smart_thresh_t *attr, int max_attrs); #endif diskscan-0.21/libscsicmd/include/ata_parse.h000066400000000000000000000354151456470715000211230ustar00rootroot00000000000000/* Generated file, do not edit */ #ifndef ATA_PARSE_H #define ATA_PARSE_H #include "ata.h" static inline bool ata_get_ata_identify_smart_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 85); return val & (1 << 0); } static inline bool ata_get_ata_identify_sct_write_same_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 206); return val & (1 << 2); } static inline bool ata_get_ata_identify_extended_number_of_user_addressable_sectors(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 3); } static inline bool ata_get_ata_identify_sense_data_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 119); return val & (1 << 6); } static inline bool ata_get_ata_identify_fields_valid_words_64_70(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 53); return val & (1 << 1); } static inline bool ata_get_ata_identify_crypto_scramble_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 59); return val & (1 << 13); } static inline bool ata_get_ata_identify_rzat_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 5); } static inline ata_qword_t ata_get_ata_identify_extended_num_user_addressable_sectors(const unsigned char *buf) { return ata_get_qword(buf, 230); } static inline bool ata_get_ata_identify_wwn_64bit_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 84); return val & (1 << 8); } static inline bool ata_get_ata_identify_standby_timer_values_settable(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 49); return val & (1 << 13); } static inline bool ata_get_ata_identify_write_buffer_dma_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 10); } static inline void ata_get_ata_identify_fw_rev(const unsigned char *buf, char *out) { ata_get_string(buf, 23, 26, out); } static inline bool ata_get_ata_identify_sata_software_settings_preservation_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 79); return val & (1 << 6); } static inline bool ata_get_ata_identify_sata_device_initiated_power_management_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 79); return val & (1 << 3); } static inline bool ata_get_ata_identify_write_uncorrectable_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 120); return val & (1 << 2); } static inline bool ata_get_ata_identify_sct_command_transport_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 206); return val & (1 << 0); } static inline ata_longword_t ata_get_ata_identify_wwn_high(const unsigned char *buf) { return ata_get_longword(buf, 108); } static inline bool ata_get_ata_identify_supports_sata_gen1_1_5gbps(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 1); } static inline bool ata_get_ata_identify_supports_receipt_of_host_initiated_power_management_requests(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 9); } static inline bool ata_get_ata_identify_supports_receive_fpdma_queued(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 77); return val & (1 << 6); } static inline bool ata_get_ata_identify_smart_self_test_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 84); return val & (1 << 1); } static inline bool ata_get_ata_identify_overwrite_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 59); return val & (1 << 14); } static inline unsigned ata_get_ata_identify_queue_depth(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 75); return (val >> 0) & ((1<<(4 - 0 + 1)) - 1); } static inline bool ata_get_ata_identify_encrypt_all_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 4); } static inline bool ata_get_ata_identify_write_buffer_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 12); } static inline bool ata_get_ata_identify_streaming_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 84); return val & (1 << 4); } static inline bool ata_get_ata_identify_download_microcode_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 83); return val & (1 << 0); } static inline bool ata_get_ata_identify_response_incomplete(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 0); return val & (1 << 2); } static inline bool ata_get_ata_identify_sct_feature_control_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 206); return val & (1 << 4); } static inline bool ata_get_ata_identify_puis_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 83); return val & (1 << 5); } static inline bool ata_get_ata_identify_supports_read_log_dma_ext_as_read_log_dma(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 15); } static inline void ata_get_ata_identify_serial_number(const unsigned char *buf, char *out) { ata_get_string(buf, 10, 19, out); } static inline bool ata_get_ata_identify_supports_host_automatic_partial_to_slumber(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 13); } static inline bool ata_get_ata_identify_cfa_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 83); return val & (1 << 2); } static inline bool ata_get_ata_identify_sata_in_order_data_delivery_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 79); return val & (1 << 4); } static inline bool ata_get_ata_identify_major_version_acs_2(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 80); return val & (1 << 9); } static inline void ata_get_ata_identify_additional_product_identifier(const unsigned char *buf, char *out) { ata_get_string(buf, 170, 173, out); } static inline bool ata_get_ata_identify_volatile_write_cache_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 5); } static inline bool ata_get_ata_identify_smart_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 0); } static inline bool ata_get_ata_identify_sct_data_tables_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 206); return val & (1 << 5); } static inline bool ata_get_ata_identify_supports_dev_automatic_partial_to_slumber(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 14); } static inline unsigned ata_get_ata_identify_current_negotiated_link_speed(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 77); return (val >> 1) & ((1<<(3 - 1 + 1)) - 1); } static inline bool ata_get_ata_identify_supports_sata_gen2_3gbps(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 2); } static inline bool ata_get_ata_identify_read_look_ahead_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 6); } static inline bool ata_get_ata_identify_read_buffer_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 13); } static inline bool ata_get_ata_identify_cfast_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 15); } static inline bool ata_get_ata_identify_lps_misalignment_reporting_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 13); } static inline bool ata_get_ata_identify_supports_ncq_priority(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 12); } static inline bool ata_get_ata_identify_address_48bit_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 83); return val & (1 << 10); } static inline bool ata_get_ata_identify_set_max_set_password_dma_and_set_max_unlock_dma_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 9); } static inline bool ata_get_ata_identify_apm_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 83); return val & (1 << 3); } static inline bool ata_get_ata_identify_sata_dma_setup_auto_activation_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 79); return val & (1 << 2); } static inline bool ata_get_ata_identify_major_version_ata_atapi_7(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 80); return val & (1 << 7); } static inline bool ata_get_ata_identify_major_version_ata_atapi_6(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 80); return val & (1 << 6); } static inline bool ata_get_ata_identify_major_version_ata_atapi_5(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 80); return val & (1 << 5); } static inline bool ata_get_ata_identify_sct_error_recovery_control_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 206); return val & (1 << 3); } static inline bool ata_get_ata_identify_block_erase_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 59); return val & (1 << 15); } static inline bool ata_get_ata_identify_gpl_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 84); return val & (1 << 5); } static inline bool ata_get_ata_identify_dma_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 49); return val & (1 << 8); } static inline unsigned ata_get_ata_identify_rotational_rate(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 216); return (val >> 0) & ((1<<(15 - 0 + 1)) - 1); } static inline bool ata_get_ata_identify_not_ata_device(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 0); return val & (1 << 15); } static inline bool ata_get_ata_identify_spin_up_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 83); return val & (1 << 6); } static inline bool ata_get_ata_identify_read_buffer_dma_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 11); } static inline bool ata_get_ata_identify_address_28bit_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 6); } static inline bool ata_get_ata_identify_supports_sata_gen3_6gbps(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 3); } static inline bool ata_get_ata_identify_download_microcode_dma_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 8); } static inline bool ata_get_ata_identify_mandatory_power_management_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 3); } static inline bool ata_get_ata_identify_fields_valid_word_88(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 53); return val & (1 << 2); } static inline bool ata_get_ata_identify_packet_feature_set_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 4); } static inline bool ata_get_ata_identify_nop_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 14); } static inline bool ata_get_ata_identify_supports_ncq_queue_management_commands(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 77); return val & (1 << 5); } static inline bool ata_get_ata_identify_write_uncorrectable_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 119); return val & (1 << 2); } static inline bool ata_get_ata_identify_supports_sata_phy_event_counters_log(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 10); } static inline bool ata_get_ata_identify_supports_ncq(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 8); } static inline bool ata_get_ata_identify_supports_ncq_streaming(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 77); return val & (1 << 4); } static inline bool ata_get_ata_identify_sata_automatic_partial_to_slumber_transitions_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 79); return val & (1 << 7); } static inline void ata_get_ata_identify_current_media_serial(const unsigned char *buf, char *out) { ata_get_string(buf, 176, 205, out); } static inline bool ata_get_ata_identify_major_version_ata_8_acs(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 80); return val & (1 << 8); } static inline ata_longword_t ata_get_ata_identify_wwn_low(const unsigned char *buf) { return ata_get_longword(buf, 110); } static inline bool ata_get_ata_identify_trusted_computing_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 48); return val & (1 << 0); } static inline bool ata_get_ata_identify_sata_non_zero_buffer_offsets_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 79); return val & (1 << 1); } static inline bool ata_get_ata_identify_non_volatile_cache(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 2); } static inline bool ata_get_ata_identify_iordy_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 49); return val & (1 << 11); } static inline bool ata_get_ata_identify_sata_hardware_feature_control_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 79); return val & (1 << 5); } static inline bool ata_get_ata_identify_supports_unload_while_ncq_outstanding(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 76); return val & (1 << 11); } static inline bool ata_get_ata_identify_security_feature_set_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 82); return val & (1 << 1); } static inline bool ata_get_ata_identify_smart_error_logging_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 84); return val & (1 << 0); } static inline bool ata_get_ata_identify_sense_data_enabled(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 120); return val & (1 << 6); } static inline bool ata_get_ata_identify_iordy_disable_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 49); return val & (1 << 10); } static inline bool ata_get_ata_identify_sanitize_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 59); return val & (1 << 12); } static inline void ata_get_ata_identify_model(const unsigned char *buf, char *out) { ata_get_string(buf, 27, 46, out); } static inline bool ata_get_ata_identify_drat_supported(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, 69); return val & (1 << 14); } static inline ata_longword_t ata_get_ata_identify_total_addressable_sectors_28bit(const unsigned char *buf) { return ata_get_longword(buf, 60); } #endif diskscan-0.21/libscsicmd/include/ata_smart.h000066400000000000000000000014651456470715000211350ustar00rootroot00000000000000#ifndef LIBSCSICMD_ATA_SMART_H #define LIBSCSICMD_ATA_SMART_H #include "smartdb.h" #include "ata.h" /* These functions are for common information that may show up differently in different drives (or unsupported) */ int ata_smart_get_temperature(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, int *min_temp, int *max_temp); int ata_smart_get_power_on_hours(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, int *pminutes); int ata_smart_get_num_reallocations(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table); int ata_smart_get_num_pending_reallocations(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table); int ata_smart_get_num_crc_errors(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table); #endif diskscan-0.21/libscsicmd/include/parse_extended_inquiry.h000066400000000000000000000040121456470715000237230ustar00rootroot00000000000000/* Copyright 2015 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_EXTENDED_INQUIRY_H #define LIBSCSICMD_EXTENDED_INQUIRY_H #include #define EVPD_MIN_LEN 4 static inline uint8_t evpd_peripheral_qualifier(uint8_t *data) { return data[0] >> 5; } static inline uint8_t evpd_peripheral_device_type(uint8_t *data) { return data[0] & 0x1F; } static inline uint8_t evpd_page_code(uint8_t *data) { return data[1]; } static inline uint16_t evpd_page_len(uint8_t *data) { return (data[2] << 8) | data[3]; } static inline uint8_t *evpd_page_data(uint8_t *data) { return data + EVPD_MIN_LEN; } static inline bool evpd_is_ascii_page(uint8_t page_code) { return 0x01 <= page_code && page_code <= 0x7F; } /* This should be called with the body of the EVPD data and not the full (i.e. with the output of evpd_page_data()) */ static inline uint16_t evpd_ascii_len(uint8_t *evpd_body) { return (evpd_body[0] << 8) | evpd_body[1]; } static inline uint8_t *evpd_ascii_data(uint8_t *evpd_body) { return evpd_body + 2; } static inline uint8_t *evpd_ascii_post_data(uint8_t *evpd_body) { return evpd_body + 2 + evpd_ascii_len(evpd_body); } static inline unsigned evpd_ascii_post_data_len(uint8_t *evpd_body, unsigned full_data_len) { return full_data_len - EVPD_MIN_LEN - 2 - evpd_ascii_len(evpd_body); } static inline bool evpd_is_valid(uint8_t *data, unsigned data_len) { if (data_len < EVPD_MIN_LEN) return false; if (evpd_page_len(data) > data_len) return false; return true; } #endif diskscan-0.21/libscsicmd/include/parse_log_sense.h000066400000000000000000000102751456470715000223310ustar00rootroot00000000000000/* Copyright 2015 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_LOG_SENSE_H #define LIBSCSICMD_LOG_SENSE_H #include "scsicmd_utils.h" #include #include /* Log Sense Header decode */ #define LOG_SENSE_MIN_LEN 4 static inline uint8_t log_sense_page_code(uint8_t *data) { return data[0] & 0x3F; } static inline bool log_sense_subpage_format(uint8_t *data) { return data[0] & 0x40; } static inline bool log_sense_data_saved(uint8_t *data) { return data[0] & 0x80; } static inline uint8_t log_sense_subpage_code(uint8_t *data) { return data[1]; } static inline unsigned log_sense_data_len(uint8_t *data) { return get_uint16(data, 2); } static inline uint8_t *log_sense_data(uint8_t *data) { return data + LOG_SENSE_MIN_LEN; } static inline uint8_t *log_sense_data_end(uint8_t *data, unsigned data_len) { return data + safe_len(data, data_len, log_sense_data(data), log_sense_data_len(data)); } static inline bool log_sense_is_valid(uint8_t *data, unsigned data_len) { if (data_len < LOG_SENSE_MIN_LEN) return false; if (!log_sense_subpage_format(data) && log_sense_subpage_code(data) != 0) return false; if (log_sense_data_len(data) + LOG_SENSE_MIN_LEN < data_len) return false; return true; } /* Log Sense Parameter decode */ #define LOG_SENSE_MIN_PARAM_LEN 4 #define LOG_PARAM_FLAG_DU 0x80 #define LOG_PARAM_FLAG_TSD 0x20 #define LOG_PARAM_FLAG_ETC 0x10 #define LOG_PARAM_FLAG_TMC_MASK 0x0C #define LOG_PARAM_FLAG_FMT_MASK 0x03 #define LOG_PARAM_TMC_EVERY_UPDATE 0 #define LOG_PARAM_TMC_EQUAL 1 #define LOG_PARAM_TMC_NOT_EQUAL 2 #define LOG_PARAM_TMC_GREATER 3 #define LOG_PARAM_FMT_COUNTER_STOP 0 #define LOG_PARAM_FMT_ASCII 1 #define LOG_PARAM_FMT_COUNTER_ROLLOVER 2 #define LOG_PARAM_FMT_BINARY 2 static inline uint16_t log_sense_param_code(uint8_t *param) { return get_uint16(param, 0); } inline static uint8_t log_sense_param_flags(uint8_t *param) { return param[2]; } inline static uint8_t log_sense_param_tmc(uint8_t *param) { return (log_sense_param_flags(param) & LOG_PARAM_FLAG_TMC_MASK) >> 2; } inline static uint8_t log_sense_param_fmt(uint8_t *param) { return log_sense_param_flags(param) & LOG_PARAM_FLAG_FMT_MASK; } static inline unsigned log_sense_param_len(uint8_t *param) { return param[3]; } static inline uint8_t *log_sense_param_data(uint8_t *param) { return param + LOG_SENSE_MIN_PARAM_LEN; } static inline bool log_sense_param_is_valid(uint8_t *data, unsigned data_len, uint8_t *param) { if (param < data) return false; const unsigned param_offset = param - data; if (param_offset > data_len) return false; if (param_offset + LOG_SENSE_MIN_PARAM_LEN > data_len) return false; if (param_offset + LOG_SENSE_MIN_PARAM_LEN + log_sense_param_len(param) > data_len) return false; return true; } #define for_all_log_sense_params(data, data_len, param) \ for (param = log_sense_data(data); \ log_sense_param_is_valid(data, data_len, param); \ param = param + LOG_SENSE_MIN_PARAM_LEN + log_sense_param_len(param)) #define for_all_log_sense_pg_0_supported_pages(data, data_len, supported_page) \ uint8_t *__tmp; \ for (__tmp = log_sense_data(data), supported_page = __tmp[0]; __tmp < log_sense_data_end(data, data_len); __tmp++, supported_page = __tmp[0]) #define for_all_log_sense_pg_0_supported_subpages(data, data_len, supported_page, supported_subpage) \ uint8_t *__tmp; \ for (__tmp = log_sense_data(data), supported_page = __tmp[0], supported_subpage = __tmp[1]; __tmp + 1 < log_sense_data_end(data, data_len); __tmp+=2, supported_page = __tmp[0], supported_subpage = __tmp[1]) bool log_sense_page_informational_exceptions(uint8_t *page, unsigned page_len, uint8_t *asc, uint8_t *ascq, uint8_t *temperature); #endif diskscan-0.21/libscsicmd/include/parse_mode_sense.h000066400000000000000000000145321456470715000224740ustar00rootroot00000000000000/* Copyright 2015 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_MODE_SENSE_H #define LIBSCSICMD_MODE_SENSE_H #include "scsicmd_utils.h" /* Mode parameter header for the MODE SENSE 6 */ #define MODE_SENSE_6_MIN_LEN 4u static inline unsigned mode_sense_6_data_len(uint8_t *data) { return data[0]; } static inline uint8_t mode_sense_6_medium_type(uint8_t *data) { return data[1]; } static inline uint8_t mode_sense_6_device_specific_param(uint8_t *data) { return data[2]; } static inline uint8_t mode_sense_6_block_descriptor_length(uint8_t *data) { return data[3]; } static inline uint8_t *mode_sense_6_block_descriptor_data(uint8_t *data) { return data + MODE_SENSE_6_MIN_LEN; } static inline uint8_t *mode_sense_6_mode_data(uint8_t *data) { return data + MODE_SENSE_6_MIN_LEN + mode_sense_6_block_descriptor_length(data); } static inline unsigned mode_sense_6_expected_length(uint8_t *data) { return 1 + mode_sense_6_data_len(data); // Add the first byte that is not part of the mode data length } static inline unsigned mode_sense_6_mode_data_len(uint8_t *data) { return mode_sense_6_expected_length(data) - MODE_SENSE_6_MIN_LEN - mode_sense_6_block_descriptor_length(data); } static inline bool mode_sense_6_is_valid_header(uint8_t *data, unsigned data_len) { if (mode_sense_6_data_len(data) < MODE_SENSE_6_MIN_LEN-1) return false; if (data_len < (unsigned)(mode_sense_6_data_len(data)) + 1) return false; if (mode_sense_6_block_descriptor_length(data) != 0 && mode_sense_6_block_descriptor_length(data) != 8) { return false; } if (mode_sense_6_data_len(data) < mode_sense_6_block_descriptor_length(data)) return false; return true; } /* Mode parameter header for the MODE SENSE 10 */ #define MODE_SENSE_10_MIN_LEN 8u static inline unsigned mode_sense_10_data_len(uint8_t *data) { return get_uint16(data, 0); } static inline uint8_t mode_sense_10_medium_type(uint8_t *data) { return data[2]; } static inline uint8_t mode_sense_10_device_specific_param(uint8_t *data) { return data[3]; } static inline bool mode_sense_10_long_lba(uint8_t *data) { return data[4] & 1; } /* SPC4 says length is times 8 without long lba and times 16 with it but it seems the value is taken verbatim */ static inline unsigned mode_sense_10_block_descriptor_length(uint8_t *data) { return get_uint16(data, 6); } static inline uint8_t *mode_sense_10_block_descriptor_data(uint8_t *data) { if (mode_sense_10_block_descriptor_length(data) > 0) return data + MODE_SENSE_10_MIN_LEN; else return NULL; } static inline uint8_t *mode_sense_10_mode_data(uint8_t *data) { return data + MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(data); } static inline unsigned mode_sense_10_expected_length(uint8_t *data) { return 2 + mode_sense_10_data_len(data); // Add the first two bytes that are not part of the mode data length } static inline unsigned mode_sense_10_mode_data_len(uint8_t *data) { return mode_sense_10_expected_length(data) - MODE_SENSE_10_MIN_LEN - mode_sense_10_block_descriptor_length(data); } static inline bool mode_sense_10_is_valid_header(uint8_t *data, unsigned data_len) { if (mode_sense_10_data_len(data) < MODE_SENSE_10_MIN_LEN-2) return false; if (data_len < (unsigned)(mode_sense_10_data_len(data)) + 2) return false; if (mode_sense_10_block_descriptor_length(data) != 0 && mode_sense_10_block_descriptor_length(data) != 8) { return false; } return true; } /* Regular block descriptor (as opposed to long) */ #define BLOCK_DESCRIPTOR_LENGTH 8 #define BLOCK_DESCRIPTOR_NUM_BLOCKS_OVERFLOW 0xFFFFFF static inline uint8_t block_descriptor_density_code(uint8_t *data) { return data[0]; } static inline uint32_t block_descriptor_num_blocks(uint8_t *data) { return get_uint24(data, 1); } static inline uint32_t block_descriptor_block_length(uint8_t *data) { return get_uint24(data, 5); } /* Mode Sense page data */ static inline uint8_t mode_sense_data_page_code(uint8_t *data) { return data[0] & 0x3F; } static inline bool mode_sense_data_subpage_format(uint8_t *data) { return data[0] & 0x40; } static inline bool mode_sense_data_parameter_saveable(uint8_t *data) { return data[0] & 0x80; } /* Caller is required to know if this is a subpage format page or not */ static inline uint8_t mode_sense_data_subpage_code(uint8_t *data) { return data[1]; } static inline unsigned mode_sense_data_page_len(uint8_t *data) { return mode_sense_data_subpage_format(data) ? 3 + (unsigned)(get_uint16(data, 2)) : 2 + (unsigned)(data[1]); } static inline unsigned mode_sense_data_param_len(uint8_t *data) { return mode_sense_data_subpage_format(data) ? get_uint16(data, 2) : data[1]; } static inline uint8_t *mode_sense_data_param(uint8_t *data) { return mode_sense_data_subpage_format(data) ? data + 4 : data + 2; } static inline bool mode_sense_data_param_is_valid(uint8_t *data, unsigned data_len) { if (data_len < 2) return false; if (mode_sense_data_page_code(data) == 0) return false; if (mode_sense_data_subpage_format(data) && data_len < 4) return false; if (data_len < mode_sense_data_page_len(data)) return false; return true; } #define for_all_mode_sense_pages(data, data_len, mode_data, mode_data_len, page, remaining_len) \ for (remaining_len = mode_data - data + safe_len(data, data_len, mode_data, mode_data_len), page = mode_data; \ remaining_len >= 3 && mode_sense_data_param_is_valid(page, remaining_len); \ remaining_len += mode_sense_data_param_len(page), page += mode_sense_data_page_len(page)) #define for_all_mode_sense_6_pages(data, data_len, page, remaining_len) \ for_all_mode_sense_pages(data, data_len, mode_sense_6_mode_data(data), mode_sense_6_mode_data_len(data), page, remaining_len) #define for_all_mode_sense_10_pages(data, data_len, page, remaining_len) \ for_all_mode_sense_pages(data, data_len, mode_sense_10_mode_data(data), mode_sense_10_mode_data_len(data), page, remaining_len) #endif diskscan-0.21/libscsicmd/include/parse_read_defect_data.h000066400000000000000000000113721456470715000235700ustar00rootroot00000000000000/* Copyright 2015 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_READ_DEFECT_DATA_H #define LIBSCSICMD_READ_DEFECT_DATA_H #include "scsicmd_utils.h" #include "scsicmd.h" #include #include const char *read_defect_data_format_to_str(uint8_t fmt); /* READ DEFECT DATA 10 */ #define READ_DEFECT_DATA_10_MIN_LEN 4 static inline bool read_defect_data_10_is_plist_valid(uint8_t *data) { return data[1] & 0x10; } static inline bool read_defect_data_10_is_glist_valid(uint8_t *data) { return data[1] & 0x08; } static inline uint8_t read_defect_data_10_list_format(uint8_t *data) { return data[1] & 0x07; } static inline uint16_t read_defect_data_10_len(uint8_t *data) { return get_uint16(data, 2); } /* For READ DEFECT DATA 10 the user may ask for only the header and the data is never really transfered, allow for this seperation in the checks. */ static inline bool read_defect_data_10_hdr_is_valid(uint8_t *data, unsigned data_len) { if (data_len < READ_DEFECT_DATA_10_MIN_LEN) return false; if ((read_defect_data_10_len(data) % 4) != 0) return false; return true; } static inline bool read_defect_data_10_is_valid(uint8_t *data, unsigned data_len) { if (!read_defect_data_10_hdr_is_valid(data, data_len)) return false; if ((unsigned)read_defect_data_10_len(data) + READ_DEFECT_DATA_10_MIN_LEN < data_len) return false; return true; } static inline uint8_t *read_defect_data_10_data(uint8_t *data) { return data + READ_DEFECT_DATA_10_MIN_LEN; } /* READ DEFECT DATA 10 */ #define READ_DEFECT_DATA_12_MIN_LEN 8 static inline bool read_defect_data_12_is_plist_valid(uint8_t *data) { return data[1] & 0x10; } static inline bool read_defect_data_12_is_glist_valid(uint8_t *data) { return data[1] & 0x08; } static inline uint8_t read_defect_data_12_list_format(uint8_t *data) { return data[1] & 0x07; } static inline uint32_t read_defect_data_12_len(uint8_t *data) { return get_uint32(data, 4); } /* For READ DEFECT DATA 10 the user may ask for only the header and the data is never really transfered, allow for this seperation in the checks. */ static inline bool read_defect_data_12_hdr_is_valid(uint8_t *data, unsigned data_len) { if (data_len < READ_DEFECT_DATA_12_MIN_LEN) return false; if ((read_defect_data_12_len(data) % 4) != 0) return false; return true; } static inline bool read_defect_data_12_is_valid(uint8_t *data, unsigned data_len) { if (!read_defect_data_12_hdr_is_valid(data, data_len)) return false; if (read_defect_data_12_len(data) + READ_DEFECT_DATA_12_MIN_LEN < data_len) return false; return true; } static inline uint8_t *read_defect_data_12_data(uint8_t *data) { return data + READ_DEFECT_DATA_12_MIN_LEN; } /* Formats */ /* Short format */ #define FORMAT_ADDRESS_SHORT_LEN 4 static inline uint32_t format_address_short_lba(uint8_t *data) { return get_uint32(data, 0); } /* Long format */ #define FORMAT_ADDRESS_LONG_LEN 8 static inline uint32_t format_address_long_lba(uint8_t *data) { return get_uint64(data, 0); } /* Byte from index */ #define FORMAT_ADDRESS_BYTE_FROM_INDEX_LEN 8 static inline uint32_t format_address_byte_from_index_cylinder(uint8_t *data) { return get_uint24(data, 0); } static inline uint8_t format_address_byte_from_index_head(uint8_t *data) { return data[3]; } static inline uint32_t format_address_byte_from_index_bytes(uint8_t *data) { return get_uint32(data, 4); } #define FORMAT_ADDRESS_BYTE_FROM_INDEX_ALL_TRACK 0xFFFFFFFF /* Physical sector format */ #define FORMAT_ADDRESS_PHYSICAL_LEN 8 static inline uint32_t format_address_physical_cylinder(uint8_t *data) { return get_uint24(data, 0); } static inline uint8_t format_address_physical_head(uint8_t *data) { return data[3]; } static inline uint32_t format_address_physical_sector(uint8_t *data) { return get_uint32(data, 4); } #define FORMAT_ADDRESS_PHYSICAL_ALL_TRACK 0xFFFFFFFF static inline unsigned read_defect_data_fmt_len(address_desc_format_e fmt) { switch (fmt) { case ADDRESS_FORMAT_SHORT: return FORMAT_ADDRESS_SHORT_LEN; case ADDRESS_FORMAT_LONG: return FORMAT_ADDRESS_LONG_LEN; case ADDRESS_FORMAT_INDEX_OFFSET: return FORMAT_ADDRESS_BYTE_FROM_INDEX_LEN; case ADDRESS_FORMAT_PHYSICAL: return FORMAT_ADDRESS_PHYSICAL_LEN; case ADDRESS_FORMAT_VENDOR: return 4; default: return 0; } } #endif diskscan-0.21/libscsicmd/include/parse_receive_diagnostics.h000066400000000000000000000073301456470715000243620ustar00rootroot00000000000000/* Copyright 2015 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_RECEIVE_DIAGNOSTICS_H #define LIBSCSICMD_RECEIVE_DIAGNOSTICS_H #include "scsicmd_utils.h" #include #include #define RECV_DIAG_MIN_LEN 4 static inline uint8_t recv_diag_get_page_code(uint8_t *data) { return data[0]; } static inline uint8_t recv_diag_get_page_code_specific(uint8_t *data) { return data[1]; } static inline uint16_t recv_diag_get_len(uint8_t *data) { return (data[2] << 8) | data[3]; } static inline uint8_t *recv_diag_data(uint8_t *data) { return data + RECV_DIAG_MIN_LEN; } static inline bool recv_diag_is_valid(uint8_t *data, unsigned data_len) { if (data_len < RECV_DIAG_MIN_LEN) return false; if ((unsigned)recv_diag_get_len(data) + RECV_DIAG_MIN_LEN > data_len) return false; return true; } /* SES Page 1 Configuration */ static inline bool ses_config_is_valid(uint8_t *data, unsigned data_len) { if (data_len < 8) return false; if (recv_diag_get_len(data) < 4) return false; return true; } static inline uint8_t ses_config_num_sub_enclosures(uint8_t *data) { return data[1] + 1; // +1 for primary } static inline uint32_t ses_config_generation(uint8_t *data) { return get_uint32(data, 4); } static inline uint8_t *ses_config_sub_enclosure(uint8_t *data) { return data + 8; } /* Enclosure Descriptor */ static inline uint8_t ses_config_enclosure_descriptor_process_identifier(uint8_t *data) { return (data[0] >> 4) & 0x7; } static inline uint8_t ses_config_enclosure_descriptor_num_processes(uint8_t *data) { return data[0] & 0x7; } static inline uint8_t ses_config_enclosure_descriptor_subenclosure_identifier(uint8_t *data) { return data[1]; } static inline uint8_t ses_config_enclosure_descriptor_num_type_descriptors(uint8_t *data) { return data[2]; } static inline uint8_t ses_config_enclosure_descriptor_len(uint8_t *data) { return data[3]; } static inline uint64_t ses_config_enclosure_descriptor_logical_identifier(uint8_t *data) { return get_uint64(data, 4); } static inline bool ses_config_enclosure_descriptor_is_valid(uint8_t *data, unsigned data_len) { if (data_len < 12) return false; if (ses_config_enclosure_descriptor_len(data) < 36 || ses_config_enclosure_descriptor_len(data) > 252 || ses_config_enclosure_descriptor_len(data) > data_len) { return false; } return true; } static inline void _ses_str_cpy(uint8_t *src, unsigned src_len, char *s, unsigned slen) { if (slen > src_len) slen = src_len; else slen--; memcpy(s, src, slen); s[slen] = 0; } static inline void ses_config_enclosure_descriptor_vendor_identifier(uint8_t *data, char *s, unsigned slen) { _ses_str_cpy(data+12, 8, s, slen); } static inline void ses_config_enclosure_descriptor_product_identifier(uint8_t *data, char *s, unsigned slen) { _ses_str_cpy(data+20, 16, s, slen); } static inline void ses_config_enclosure_descriptor_revision_level(uint8_t *data, char *s, unsigned slen) { _ses_str_cpy(data+36, 4, s, slen); } static inline uint8_t *ses_config_enclosure_descriptor_vendor_info(uint8_t *data) { return data + 40; } static inline uint8_t ses_config_enclosure_descriptor_vendor_len(uint8_t *data) { return ses_config_enclosure_descriptor_len(data) + 4 - 40; } #endif diskscan-0.21/libscsicmd/include/scsicmd.h000066400000000000000000000202541456470715000206040ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_H #define LIBSCSICMD_H #include #include #include "sense_key_list.h" #include "asc_num_list.h" #define SCSI_VENDOR_LEN 8 #define SCSI_MODEL_LEN 16 #define SCSI_FW_REVISION_LEN 4 #define SCSI_SERIAL_LEN 8 typedef char scsi_vendor_t[SCSI_VENDOR_LEN+1]; typedef char scsi_model_t[SCSI_MODEL_LEN+1]; typedef char scsi_fw_revision_t[SCSI_FW_REVISION_LEN+1]; typedef char scsi_serial_t[SCSI_SERIAL_LEN+1]; #undef SENSE_KEY_MAP #define SENSE_KEY_MAP(_name_, _val_) SENSE_KEY_##_name_ = _val_, enum sense_key_e { SENSE_KEY_LIST }; #undef SENSE_KEY_MAP const char *sense_key_to_name(enum sense_key_e sense_key); const char *asc_num_to_name(uint8_t asc, uint8_t ascq); int cdb_tur(unsigned char *cdb); #define SCSI_DEVICE_TYPE_LIST \ X(BLOCK) \ X(SEQ) \ X(PRINTER) \ X(PROCESSOR) \ X(WRITE_ONCE) \ X(CD) \ X(SCANNER) \ X(OPTICAL) \ X(MEDIA_CHANGER) \ X(COMMUNICATION) \ X(OBSOLETE_A) \ X(OBSOLETE_B) \ X(RAID) \ X(SES) \ X(RBC) \ X(OCRW) \ X(BCC) \ X(OSD) \ X(ADC2) \ X(SECURITY_MGR) \ X(RESERVED_14) \ X(RESERVED_15) \ X(RESERVED_16) \ X(RESERVED_17) \ X(RESERVED_18) \ X(RESERVED_19) \ X(RESERVED_1A) \ X(RESERVED_1B) \ X(RESERVED_1C) \ X(RESERVED_1D) \ X(WELL_KNOWN) \ X(UNKNOWN) #undef X #define X(name) SCSI_DEV_TYPE_ ## name, typedef enum scsi_device_type_e { SCSI_DEVICE_TYPE_LIST } scsi_device_type_e; #undef X const char *scsi_device_type_name(scsi_device_type_e dev_type); #define SCSI_PROTOCOL_IDENTIFIER_LIST \ X(FC, 0, "Fibre Channel") \ X(PARALLEL_SCSI, 1, "Parallel SCSI") \ X(SSA, 2, "SSA") \ X(IEEE1394, 3, "IEEE 1394") \ X(SRP, 4, "SCSI Remote DMA") \ X(ISCSI, 5, "iSCSI") \ X(SAS, 6, "SAS") \ X(ADT, 7, "Automation Drive Interface") \ X(ATA, 8, "ATA/ATAPI") \ X(RESERVED_9, 9, "Reserved9") \ X(RESERVED_A, 10, "Reserved10") \ X(RESERVED_B, 11, "Reserved11") \ X(RESERVED_C, 12, "Reserved12") \ X(RESERVED_D, 13, "Reserved13") \ X(RESERVED_E, 14, "Reserved14") \ X(NONE, 15, "No Specific Protocol") #undef X #define X(name, val, str) SCSI_PROTOCOL_IDENTIFIER_ ## name, typedef enum scsi_protocol_identifier_e { SCSI_PROTOCOL_IDENTIFIER_LIST } scsi_protocol_identifier_e; #undef X typedef struct ata_status_t { uint8_t extend; uint8_t error; uint8_t device; uint8_t status; uint16_t sector_count; uint64_t lba; } ata_status_t; /* sense parser */ typedef struct sense_info_t { bool is_fixed; // Else descriptor based bool is_current; // Else for previous request uint8_t sense_key; uint8_t asc; uint8_t ascq; bool information_valid; uint64_t information; bool cmd_specific_valid; uint64_t cmd_specific; bool sense_key_specific_valid; union { struct { bool command_error; bool bit_pointer_valid; uint8_t bit_pointer; uint16_t field_pointer; } illegal_request; struct { uint16_t actual_retry_count; } hardware_medium_recovered_error; struct { double progress; } not_ready; struct { bool segment_descriptor; bool bit_pointer_valid; uint8_t bit_pointer; uint16_t field_pointer; } copy_aborted; struct { bool overflow; } unit_attention; } sense_key_specific; bool fru_code_valid; uint8_t fru_code; bool ata_status_valid; ata_status_t ata_status; bool incorrect_len_indicator; uint32_t vendor_unique_error; } sense_info_t; bool scsi_parse_sense(unsigned char *sense, int sense_len, sense_info_t *info); /* inquiry */ /** Build a CDB from the inquiry command. */ int cdb_inquiry(unsigned char *cdb, bool evpd, char page_code, uint16_t alloc_len); /** Build a CDB from the simple inquiry command that returns the basic information. * The size can be up to 256 bytes but in order to be able to handle older SCSI devices it is recommended to use the size of 96 bytes. */ static inline int cdb_inquiry_simple(unsigned char *cdb, uint16_t alloc_len) { return cdb_inquiry(cdb, 0, 0, alloc_len); } /** Parse the simple inquiry page data. */ bool parse_inquiry(unsigned char *buf, unsigned buf_len, int *device_type, scsi_vendor_t vendor, scsi_model_t model, scsi_fw_revision_t rev, scsi_serial_t serial); /* read capacity */ // READ CAPACITY 10 expects a buffer of 8 bytes int cdb_read_capacity_10(unsigned char *cdb); bool parse_read_capacity_10(unsigned char *buf, unsigned buf_len, uint32_t *max_lba, uint32_t *block_size); // READ CAPACITY 16 allows to set the receive buffer size but it should be at least 32 bytes int cdb_read_capacity_16(unsigned char *cdb, uint32_t alloc_len); bool parse_read_capacity_16(unsigned char *buf, unsigned buf_len, uint64_t *max_lba, uint32_t *block_size, bool *prot_enable, unsigned *p_type, unsigned *p_i_exponent, unsigned *logical_blocks_per_physical_block_exponent, bool *thin_provisioning_enabled, bool *thin_provisioning_zero, unsigned *lowest_aligned_lba); static inline bool parse_read_capacity_16_simple(unsigned char *buf, unsigned buf_len, uint64_t *max_lba, uint32_t *block_size) { return parse_read_capacity_16(buf, buf_len, max_lba, block_size, 0, 0, 0, 0, 0, 0, 0); } /* read & write */ int cdb_read_10(unsigned char *cdb, bool fua, uint64_t lba, uint16_t transfer_length_blocks); int cdb_write_10(unsigned char *cdb, bool fua, uint64_t lba, uint16_t transfer_length_blocks); int cdb_read_16(unsigned char *cdb, bool fua, bool fua_nv, bool dpo, uint64_t lba, uint32_t transfer_length_blocks); int cdb_write_16(unsigned char *cdb, bool dpo, bool fua, bool fua_nv, uint64_t lba, uint32_t transfer_length_blocks); /* log sense */ int cdb_log_sense(unsigned char *cdb, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len); /* mode sense */ typedef enum { PAGE_CONTROL_CURRENT = 0, PAGE_CONTROL_CHANGEABLE = 1, PAGE_CONTROL_DEFAULT = 2, PAGE_CONTROL_SAVED = 3, } page_control_e; int cdb_mode_sense_6(unsigned char *cdb, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint8_t alloc_len); int cdb_mode_sense_10(unsigned char *cdb, bool long_lba_accepted, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len); /* send/receive diagnostics */ int cdb_receive_diagnostics(unsigned char *cdb, bool page_code_valid, uint8_t page_code, uint16_t alloc_len); typedef enum { SELF_TEST_ZERO = 0, SELF_TEST_BACKGROUND_SHORT = 1, SELF_TEST_BACKGROUND_EXTENDED = 2, SELF_TEST_RESERVED1 = 3, SELF_TEST_BACKGROUND_ABORT = 4, SELF_TEST_FOREGROUND_SHORT = 5, SELF_TEST_FOREGROUND_EXTENDED = 6, SELF_TEST_RESERVED2 = 7, } self_test_code_e; int cdb_send_diagnostics(unsigned char *cdb, self_test_code_e self_test, uint16_t param_len); /* read defect data */ typedef enum { ADDRESS_FORMAT_SHORT = 0, ADDRESS_FORMAT_RESERVED_1 = 1, ADDRESS_FORMAT_RESERVED_2 = 2, ADDRESS_FORMAT_LONG = 3, ADDRESS_FORMAT_INDEX_OFFSET = 4, ADDRESS_FORMAT_PHYSICAL = 5, ADDRESS_FORMAT_VENDOR = 6, ADDRESS_FORMAT_RESERVED_3 = 7, } address_desc_format_e; int cdb_read_defect_data_10(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint16_t alloc_len); int cdb_read_defect_data_12(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint32_t alloc_len); #endif diskscan-0.21/libscsicmd/include/scsicmd_utils.h000066400000000000000000000034751456470715000220320ustar00rootroot00000000000000/* Copyright 2015 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_UTILS_H #define LIBSCSICMD_UTILS_H #include static inline uint16_t get_uint16(unsigned char *buf, int start) { return (uint16_t)buf[start] << 8 | (uint16_t)buf[start+1]; } static inline uint32_t get_uint24(unsigned char *buf, int start) { return (uint32_t)buf[start] << 16 | (uint32_t)buf[start+1] << 8 | (uint32_t)buf[start+2]; } static inline uint32_t get_uint32(unsigned char *buf, int start) { return (uint32_t)buf[start] << 24 | (uint32_t)buf[start+1] << 16 | (uint32_t)buf[start+2] << 8 | (uint32_t)buf[start+3]; } static inline uint64_t get_uint64(unsigned char *buf, int start) { return (uint64_t)buf[start] << 56 | (uint64_t)buf[start+1] << 48 | (uint64_t)buf[start+2] << 40 | (uint64_t)buf[start+3] << 32 | (uint64_t)buf[start+4] << 24 | (uint64_t)buf[start+5] << 16 | (uint64_t)buf[start+6] << 8 | (uint64_t)buf[start+7]; } static inline unsigned safe_len(uint8_t *start, unsigned len, uint8_t *subbuf, unsigned subbuf_len) { const int start_offset = subbuf - start; if (start_offset < 0 || (unsigned)start_offset > len) return 0; if (subbuf_len + start_offset > len) return len - start_offset; else return subbuf_len; } #endif diskscan-0.21/libscsicmd/include/sense_key_list.h000066400000000000000000000025601456470715000221770ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #ifndef LIBSCSICMD_SENSE_KEY_LIST_H #define LIBSCSICMD_SENSE_KEY_LIST_H #define SENSE_KEY_LIST \ SENSE_KEY_MAP(NO_SENSE, 0x0) \ SENSE_KEY_MAP(RECOVERED_ERROR, 0x1) \ SENSE_KEY_MAP(NOT_READY, 0x2) \ SENSE_KEY_MAP(MEDIUM_ERROR, 0x3) \ SENSE_KEY_MAP(HARDWARE_ERROR, 0x4) \ SENSE_KEY_MAP(ILLEGAL_REQUEST, 0x5) \ SENSE_KEY_MAP(UNIT_ATTENTION, 0x6) \ SENSE_KEY_MAP(DATA_PROTECT, 0x7) \ SENSE_KEY_MAP(BLANK_CHECK, 0x8) \ SENSE_KEY_MAP(VENDOR_SPECIFIC, 0x9) \ SENSE_KEY_MAP(COPY_ABORTED, 0xA) \ SENSE_KEY_MAP(ABORTED_COMMAND, 0xB) \ SENSE_KEY_MAP(RESERVED_C, 0xC) \ SENSE_KEY_MAP(VOLUME_OVERFLOW, 0xD) \ SENSE_KEY_MAP(MISCOMPARE, 0xE) \ SENSE_KEY_MAP(COMPLETED, 0xF) #endif diskscan-0.21/libscsicmd/include/smartdb.h000066400000000000000000000016561456470715000206200ustar00rootroot00000000000000#ifndef LIBSCSICMD_SMARTDB_H #define LIBSCSICMD_SMARTDB_H #include typedef struct smart_table smart_table_t; typedef struct smart_attr smart_attr_t; typedef enum smart_attr_type { SMART_ATTR_TYPE_NONE, SMART_ATTR_TYPE_POH, SMART_ATTR_TYPE_TEMP, SMART_ATTR_TYPE_REALLOC, SMART_ATTR_TYPE_REALLOC_PENDING, SMART_ATTR_TYPE_CRC_ERRORS, } smart_attr_type_e; typedef enum smart_attr_raw { SMART_ATTR_RAW_HEX48, SMART_ATTR_RAW_DEC48, } smart_attr_raw_e; struct smart_attr { uint8_t id; smart_attr_type_e type; smart_attr_raw_e raw; int offset; const char *name; }; struct smart_table { int num_attrs; smart_attr_t attrs[30]; }; const smart_table_t *smart_table_for_disk(const char *vendor, const char *model, const char *firmware); const smart_attr_t *smart_attr_for_id(const smart_table_t *table, uint8_t id); const smart_attr_t *smart_attr_for_type(const smart_table_t *table, smart_attr_type_e attr_type); #endif diskscan-0.21/libscsicmd/regen.sh000077500000000000000000000004101456470715000170120ustar00rootroot00000000000000#!/bin/sh echo "Regenerate generated files" src/smartdb/smartdb_gen_c.py src/smartdb/smartdb.xml > src/smartdb/smartdb_gen.c git add src/smartdb/smartdb_gen.c structs/ata_struct_2_h.py structs/ata_identify.yaml > include/ata_parse.h git add include/ata_parse.h diskscan-0.21/libscsicmd/src/000077500000000000000000000000001456470715000161475ustar00rootroot00000000000000diskscan-0.21/libscsicmd/src/CMakeLists.txt000066400000000000000000000002511456470715000207050ustar00rootroot00000000000000add_library(scsicmd STATIC ata.c ata_smart.c cdb.c parse_inquiry.c parse_read_cap.c parse_sense.c log_sense.c parse.c str_map.c smartdb/smartdb.c smartdb/smartdb_gen.c) diskscan-0.21/libscsicmd/src/ata.c000066400000000000000000000076411456470715000170700ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "ata.h" #include #include bool ata_inquiry_checksum_verify(const unsigned char *buf, int buf_len) { if (buf_len != 512) return false; if (buf[511] != 0xA5) { // Checksum isn't claimed to be valid, nothing to check here return true; } return ata_checksum_verify(buf); } bool ata_status_from_scsi_sense(unsigned char *sense, int sense_len, ata_status_t *status) { sense_info_t sense_info; assert(status); bool parsed = scsi_parse_sense(sense, sense_len, &sense_info); if (parsed && sense_info.ata_status_valid) { *status = sense_info.ata_status; return true; } if (sense_info.is_fixed) { // Fixed format parsing for ATA passthrough can't be known automatically memset(status, 0, sizeof(*status)); status->error = sense_info.information & 0xFF; status->status = (sense_info.information >> 8) & 0xFF; status->device = (sense_info.information >> 16) & 0xFF; status->sector_count = (sense_info.information >> 24) & 0xFF; status->extend = sense_info.cmd_specific & 0x80; uint32_t lba_high = (sense_info.cmd_specific >> 8) & 0xFF; uint32_t lba_mid = (sense_info.cmd_specific >> 16) & 0xFF; uint32_t lba_low = (sense_info.cmd_specific >> 24) & 0xFF; status->lba = (lba_high << 16) | (lba_mid << 8) | lba_low; // TODO: sector_count_upper_non_zero: sense_info.cmd_specific & 0x40 // TODO: lba upper non zero: sense_info.cmd_specific & 0x20 // TODO: log index: sense_info.cmd_specific & 0x07 } return false; } /* ATA SMART READ DATA */ uint16_t ata_get_ata_smart_read_data_version(const unsigned char *buf) { return ata_get_word(buf, 0); } int ata_parse_ata_smart_read_data(const unsigned char *buf, ata_smart_attr_t *attrs, int max_attrs) { if (!ata_check_ata_smart_read_data_checksum(buf)) return -1; /* // Some disks do not return this expected value (Ticket #55) if (ata_get_ata_smart_read_data_version(buf) != 0x0010) return -1; */ int i, j; for (i = 0, j = 0; i < MAX_SMART_ATTRS && i < max_attrs; i++) { const unsigned char *raw_attr = buf + 2 + 12*i; ata_smart_attr_t *attr = &attrs[j]; attr->id = raw_attr[0]; if (attr->id == 0) // Skip an invalid attribute continue; attr->status = raw_attr[1] | raw_attr[2]<<8; attr->value = raw_attr[3]; attr->min = raw_attr[4]; attr->raw = (raw_attr[5]) | (raw_attr[6] << 8) | (raw_attr[7] << 16) | (raw_attr[8] << 24) | ((uint64_t)raw_attr[9] << 32) | ((uint64_t)raw_attr[10] << 40); j++; } return j; } int ata_parse_ata_smart_read_thresh(const unsigned char *buf, ata_smart_thresh_t *attrs, int max_attrs) { if (!ata_check_ata_smart_read_data_checksum(buf)) return -1; /* // Some disks do not return this expected value (Ticket #55) if (ata_get_ata_smart_read_data_version(buf) != 0x0010) return -1; */ int i, j; for (i = 0, j = 0; i < MAX_SMART_ATTRS && i < max_attrs; i++) { const unsigned char *raw_attr = buf + 2 + 12*i; ata_smart_thresh_t *attr = &attrs[j]; attr->id = raw_attr[0]; if (attr->id == 0) // Skip an invalid attribute continue; attr->threshold = raw_attr[1]; j++; } return j; } diskscan-0.21/libscsicmd/src/ata_smart.c000066400000000000000000000046551456470715000203000ustar00rootroot00000000000000#include "ata_smart.h" #include static const smart_attr_t *ata_smart_get(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, const ata_smart_attr_t **pattr, smart_attr_type_e attr_type) { const smart_attr_t *attr_info; int i; attr_info = smart_attr_for_type(table, attr_type); if (attr_info == NULL) return NULL; for (i = 0; i < num_attrs; i++) { if (attrs[i].id == attr_info->id) { *pattr = &attrs[i]; return attr_info; } } // Attribute not found in disk smart data return NULL; } static int ata_smart_get_simple(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, smart_attr_type_e attr_type) { const smart_attr_t *attr_info; const ata_smart_attr_t *smart_attr; attr_info = ata_smart_get(attrs, num_attrs, table, &smart_attr, attr_type); if (attr_info == NULL) return -1; return smart_attr->raw; } int ata_smart_get_temperature(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, int *pmin_temp, int *pmax_temp) { const smart_attr_t *attr_info; const ata_smart_attr_t *smart_attr; attr_info = ata_smart_get(attrs, num_attrs, table, &smart_attr, SMART_ATTR_TYPE_TEMP); if (attr_info == NULL) return -1; // Temperature is some offset minus the current value, usually int temp = attr_info->offset - smart_attr->value; *pmin_temp = *pmax_temp = -1; if (smart_attr->raw) { int min_temp = (smart_attr->raw >> 16) & 0xFFFF; int max_temp = (smart_attr->raw >> 32) & 0xFFFF; temp = smart_attr->raw & 0xFFFF; if (max_temp >= temp && min_temp <= temp) { *pmin_temp = min_temp; *pmax_temp = max_temp; } } return temp; } int ata_smart_get_power_on_hours(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table, int *pminutes) { *pminutes = -1; return ata_smart_get_simple(attrs, num_attrs, table, SMART_ATTR_TYPE_POH); } int ata_smart_get_num_reallocations(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table) { return ata_smart_get_simple(attrs, num_attrs, table, SMART_ATTR_TYPE_REALLOC); } int ata_smart_get_num_pending_reallocations(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table) { return ata_smart_get_simple(attrs, num_attrs, table, SMART_ATTR_TYPE_REALLOC_PENDING); } int ata_smart_get_num_crc_errors(const ata_smart_attr_t *attrs, int num_attrs, const smart_table_t *table) { return ata_smart_get_simple(attrs, num_attrs, table, SMART_ATTR_TYPE_CRC_ERRORS); } diskscan-0.21/libscsicmd/src/cdb.c000066400000000000000000000127611456470715000170520ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include static inline void set_uint16(unsigned char *cdb, int start, uint16_t val) { cdb[start] = (val >> 8) & 0xFF; cdb[start+1] = val & 0xFF; } static inline void set_uint32(unsigned char *cdb, int start, uint32_t val) { cdb[start] = (val >> 24) & 0xFF; cdb[start+1] = (val >> 16) & 0xFF; cdb[start+2] = (val >> 8) & 0xFF; cdb[start+3] = val & 0xFF; } static inline void set_uint64(unsigned char *cdb, int start, uint64_t val) { cdb[start] = (val >> 56) & 0xFF; cdb[start+1] = (val >> 48) & 0xFF; cdb[start+2] = (val >> 40) & 0xFF; cdb[start+3] = (val >> 32) & 0xFF; cdb[start+4] = (val >> 24) & 0xFF; cdb[start+5] = (val >> 16) & 0xFF; cdb[start+6] = (val >> 8) & 0xFF; cdb[start+7] = val & 0xFF; } int cdb_tur(unsigned char *cdb) { const int TUR_LEN = 6; memset(cdb, 0, TUR_LEN); return TUR_LEN; } int cdb_inquiry(unsigned char *cdb, bool evpd, char page_code, uint16_t alloc_len) { const int INQUIRY_LEN = 6; cdb[0] = 0x12; cdb[1] = evpd ? 1 : 0; cdb[2] = page_code; set_uint16(cdb, 3, alloc_len); cdb[5] = 0; return INQUIRY_LEN; } int cdb_read_capacity_10(unsigned char *cdb) { const int LEN = 10; cdb[0] = 0x25; memset(cdb+1, 0, LEN-1); return LEN; } int cdb_read_capacity_16(unsigned char *cdb, uint32_t alloc_len) { const int LEN = 16; cdb[0] = 0x9E; cdb[1] = 0x10; memset(cdb+2, 0, LEN-2); set_uint32(cdb, 10, alloc_len); return LEN; } int cdb_read_10(unsigned char *cdb, bool fua, uint64_t lba, uint16_t transfer_length_blocks) { const int LEN = 10; cdb[0] = 0x28; cdb[1] = fua << 3; set_uint32(cdb, 2, lba); cdb[6] = 0; set_uint16(cdb, 7, transfer_length_blocks); cdb[9] = 0; return LEN; } int cdb_write_10(unsigned char *cdb, bool fua, uint64_t lba, uint16_t transfer_length_blocks) { const int LEN = 10; cdb[0] = 0x2A; cdb[1] = fua << 3; set_uint32(cdb, 2, lba); cdb[6] = 0; set_uint16(cdb, 7, transfer_length_blocks); cdb[9] = 0; return LEN; } int cdb_read_16(unsigned char *cdb, bool fua, bool fua_nv, bool dpo, uint64_t lba, uint32_t transfer_length_blocks) { const int LEN = 16; cdb[0] = 0x88; cdb[1] = (dpo<<4) | (fua<<3) | (fua_nv<<1); set_uint64(cdb, 2, lba); set_uint32(cdb, 10, transfer_length_blocks); cdb[14] = 0; cdb[15] = 0; return LEN; } int cdb_write_16(unsigned char *cdb, bool dpo, bool fua, bool fua_nv, uint64_t lba, uint32_t transfer_length_blocks) { const int LEN = 16; cdb[0] = 0x8A; cdb[1] = (dpo<<4) | (fua<<3) | (fua_nv<<1); set_uint64(cdb, 2, lba); set_uint32(cdb, 10, transfer_length_blocks); cdb[14] = 0; cdb[15] = 0; return LEN; } int cdb_log_sense(unsigned char *cdb, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len) { const int LEN = 10; memset(cdb, 0, LEN); cdb[0] = 0x4D; cdb[2] = (1 << 6) | (page_code & 0x3F); // The pc is always set to 1 for Cumulative values cdb[3] = subpage_code; set_uint16(cdb, 7, alloc_len); return LEN; } int cdb_receive_diagnostics(unsigned char *cdb, bool page_code_valid, uint8_t page_code, uint16_t alloc_len) { const int LEN = 6; cdb[0] = 0x1C; cdb[1] = page_code_valid ? 1 : 0; cdb[2] = page_code; set_uint16(cdb, 3, alloc_len); cdb[5] = 0; return LEN; } int cdb_send_diagnostics(unsigned char *cdb, self_test_code_e self_test, uint16_t param_len) { const int LEN = 6; cdb[0] = 0x1D; cdb[1] = self_test << 5; cdb[2] = 0; set_uint16(cdb, 3, param_len); cdb[5] = 0; return LEN; } int cdb_mode_sense_6(unsigned char *cdb, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint8_t alloc_len) { const int LEN = 6; cdb[0] = 0x1A; cdb[1] = disable_block_descriptor ? (1<<3) : 0; cdb[2] = (page_control << 6) | page_code; cdb[3] = subpage_code; cdb[4] = alloc_len; cdb[5] = 0; return LEN; } int cdb_mode_sense_10(unsigned char *cdb, bool long_lba_accepted, bool disable_block_descriptor, page_control_e page_control, uint8_t page_code, uint8_t subpage_code, uint16_t alloc_len) { const int LEN = 10; cdb[0] = 0x5A; cdb[1] = (long_lba_accepted ? 1<<4 : 0) | (disable_block_descriptor ? 1<<3 : 0); cdb[2] = (page_control << 6) | page_code; cdb[3] = subpage_code; cdb[4] = 0; cdb[5] = 0; cdb[6] = 0; set_uint16(cdb, 7, alloc_len); cdb[9] = 0; return LEN; } int cdb_read_defect_data_10(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint16_t alloc_len) { const int LEN = 10; cdb[0] = 0x37; cdb[1] = 0; cdb[2] = (plist ? 0x10 : 0) | (glist ? 0x08 : 0) | format; cdb[3] = cdb[4] = cdb[5] = cdb[6] = 0; set_uint16(cdb, 7, alloc_len); cdb[9] = 0; return LEN; } int cdb_read_defect_data_12(unsigned char *cdb, bool plist, bool glist, address_desc_format_e format, uint32_t alloc_len) { const int LEN = 12; cdb[0] = 0xB7; cdb[1] = (plist ? 0x10 : 0) | (glist ? 0x08 : 0) | format; cdb[2] = cdb[3] = cdb[4] = cdb[5] = 0; set_uint32(cdb, 6, alloc_len); cdb[10] = 0; cdb[11] = 0; return LEN; } diskscan-0.21/libscsicmd/src/log_sense.c000066400000000000000000000012221456470715000202660ustar00rootroot00000000000000#include "parse_log_sense.h" bool log_sense_page_informational_exceptions(uint8_t *page, unsigned page_len, uint8_t *asc, uint8_t *ascq, uint8_t *temperature) { if (!log_sense_is_valid(page, page_len)) return false; if (log_sense_page_code(page) != 0x2F) return false; if (log_sense_subpage_format(page) && log_sense_subpage_code(page) != 0) return false; uint8_t *param; for_all_log_sense_params(page, page_len, param) { if (log_sense_param_code(param) == 0) { uint8_t *param_data = log_sense_param_data(param); *asc = param_data[0]; *ascq = param_data[1]; *temperature = param_data[2]; return true; } } return false; } diskscan-0.21/libscsicmd/src/parse.c000066400000000000000000000005041456470715000174240ustar00rootroot00000000000000#include "parse_read_defect_data.h" static const char *defect_data_format_str[] = { "Short", "Reserved (1)", "Reserved (2)", "Long", "Index", "Physical", "Vendor", "Reserved (7)", }; const char *read_defect_data_format_to_str(uint8_t fmt) { if (fmt > 7) return "Unknown"; return defect_data_format_str[fmt]; } diskscan-0.21/libscsicmd/src/parse_inquiry.c000066400000000000000000000040751456470715000212130ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include #include bool parse_inquiry(unsigned char *buf, unsigned buf_len, int *device_type, scsi_vendor_t vendor, scsi_model_t model, scsi_fw_revision_t revision, scsi_serial_t serial) { *device_type = -1; vendor[0] = 0; model[0] = 0; revision[0] = 0; serial[0] = 0; if (buf_len < 32) return false; unsigned char fmt = buf[3] & 0xf; int valid_len = buf[4] + 4; *device_type = buf[0] & 0x1f; if (valid_len >= 8 + SCSI_VENDOR_LEN) { strncpy(vendor, (char*)buf+8, SCSI_VENDOR_LEN); vendor[SCSI_VENDOR_LEN] = 0; } if (valid_len >= 16 + SCSI_MODEL_LEN) { strncpy(model, (char*)buf+16, SCSI_MODEL_LEN); model[SCSI_MODEL_LEN] = 0; } if (valid_len >= 32 + SCSI_FW_REVISION_LEN) { strncpy(revision, (char*)buf+32, SCSI_FW_REVISION_LEN); revision[SCSI_FW_REVISION_LEN] = 0; } if (valid_len >= 44 && fmt == 2) { strncpy(serial, (char*)buf+36, SCSI_SERIAL_LEN); serial[SCSI_SERIAL_LEN] = 0; } return true; } #define STRINGIFY(name) # name const char *scsi_device_type_name(scsi_device_type_e dev_type) { #define X(name) case SCSI_DEV_TYPE_##name: return STRINGIFY(name); switch (dev_type) { SCSI_DEVICE_TYPE_LIST #undef X } return "Unknown device type"; } diskscan-0.21/libscsicmd/src/parse_read_cap.c000066400000000000000000000036001456470715000212420ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include "scsicmd_utils.h" #include #include bool parse_read_capacity_10(unsigned char *buf, unsigned buf_len, uint32_t *max_lba, uint32_t *block_size) { if (buf_len < 8) return false; if (max_lba) *max_lba = get_uint32(buf, 0); if (block_size) *block_size = get_uint32(buf, 4); return true; } bool parse_read_capacity_16(unsigned char *buf, unsigned buf_len, uint64_t *max_lba, uint32_t *block_size, bool *prot_enable, unsigned *p_type, unsigned *p_i_exponent, unsigned *logical_blocks_per_physical_block_exponent, bool *thin_provisioning_enabled, bool *thin_provisioning_zero, unsigned *lowest_aligned_lba) { if (buf_len < 16) return false; if (max_lba) *max_lba = get_uint64(buf, 0); if (block_size) *block_size = get_uint32(buf, 8); if (prot_enable) *prot_enable = buf[12] & 1; if (p_type) *p_type = (buf[12] & 0xe) >> 1; if (p_i_exponent) *p_i_exponent = (buf[13] & 0xf0) >> 4; if (logical_blocks_per_physical_block_exponent) *logical_blocks_per_physical_block_exponent = buf[13] & 0xf; if (thin_provisioning_enabled) *thin_provisioning_enabled = buf[14] & 0x80; if (thin_provisioning_zero) *thin_provisioning_zero = buf[14] & 0x40; if (lowest_aligned_lba) *lowest_aligned_lba = (buf[14] & 0x3f) << 8 | buf[15]; return true; } diskscan-0.21/libscsicmd/src/parse_sense.c000066400000000000000000000210411456470715000206200ustar00rootroot00000000000000#include "scsicmd.h" #include "scsicmd_utils.h" #include static void parse_sense_key_specific(unsigned char *sks, sense_info_t *info) { info->sense_key_specific_valid = sks[0] & 0x80; if (info->sense_key_specific_valid) { uint32_t sense_key_specific = get_uint24(sks, 0) & 0x007FFFFF; switch (info->sense_key) { case SENSE_KEY_ILLEGAL_REQUEST: info->sense_key_specific.illegal_request.command_error = sense_key_specific & 0x400000; info->sense_key_specific.illegal_request.bit_pointer_valid = sense_key_specific & 0x080000; info->sense_key_specific.illegal_request.bit_pointer = (sense_key_specific & 0x070000) >> 16; info->sense_key_specific.illegal_request.field_pointer = sense_key_specific & 0xFFFF; break; case SENSE_KEY_HARDWARE_ERROR: case SENSE_KEY_MEDIUM_ERROR: case SENSE_KEY_RECOVERED_ERROR: info->sense_key_specific.hardware_medium_recovered_error.actual_retry_count = sense_key_specific & 0xFFFF; break; case SENSE_KEY_NOT_READY: case SENSE_KEY_NO_SENSE: info->sense_key_specific.not_ready.progress = ((double)(sense_key_specific & 0xFFFF))/65536.0; break; case SENSE_KEY_COPY_ABORTED: info->sense_key_specific.copy_aborted.segment_descriptor = sense_key_specific & 0x200000; info->sense_key_specific.copy_aborted.bit_pointer_valid = sense_key_specific & 0x080000; info->sense_key_specific.copy_aborted.bit_pointer = (sense_key_specific & 0x070000) >> 16; info->sense_key_specific.copy_aborted.field_pointer = sense_key_specific & 0xFFFF; break; case SENSE_KEY_UNIT_ATTENTION: info->sense_key_specific.unit_attention.overflow = sense_key_specific & 0x010000; break; default: info->sense_key_specific_valid = false; break; } } } static bool parse_sense_fixed(unsigned char *sense, int sense_len, sense_info_t *info) { if (sense_len < 18) return false; info->information_valid = sense[0] & 0x80; if (info->information_valid) info->information = get_uint32(sense, 3); info->incorrect_len_indicator = sense[2] & 0x20; info->sense_key = sense[2] & 0xF; info->asc = sense[12]; info->ascq = sense[13]; info->cmd_specific_valid = true; info->cmd_specific = get_uint32(sense, 8); info->fru_code_valid = true; info->fru_code = sense[14]; parse_sense_key_specific(sense + 15, info); if (sense_len >= 21) info->vendor_unique_error = get_uint16(sense, 20); //uint8_t additional_sense_len = sense[7]; return true; } static bool parse_sense_descriptor(unsigned char *sense, unsigned sense_len, sense_info_t *info) { if (sense_len < 8) return false; info->sense_key = sense[1] & 0xF; info->asc = sense[2]; info->ascq = sense[3]; unsigned additional_sense_length = sense[7]; if (sense_len > additional_sense_length + 8) sense_len = additional_sense_length + 8; unsigned idx; unsigned desc_len; for (idx = 8; idx < sense_len; idx += desc_len+2) { uint8_t desc_type = sense[idx]; desc_len = sense[idx+1]; if (idx + desc_len + 2 > sense_len) break; switch (desc_type) { case 0x00: // Information if (desc_len == 0x0A) { info->information_valid = sense[idx+2] & 0x80; info->information = get_uint64(sense, idx+4); } break; case 0x01: // Command specific information if (desc_len == 0x0A) { info->cmd_specific_valid = true; info->cmd_specific = get_uint64(sense, idx+4); } break; case 0x02: // Sense key specific if (desc_len == 0x06) { parse_sense_key_specific(sense+4, info); } break; case 0x03: // FRU if (desc_len == 0x02) { info->fru_code_valid = true; info->fru_code = sense[idx+3]; } break; case 0x04: // Stream commands break; case 0x05: // Block commands if (desc_len == 0x02) { info->incorrect_len_indicator = sense[idx+3] & 0x20; } break; case 0x06: // OSD object identification break; case 0x07: // OSD response integrity check value break; case 0x08: // OSD attribute identification break; case 0x09: // ATA Status Return if (desc_len == 0x0C) { info->ata_status_valid = true; info->ata_status.extend = sense[idx+2] & 1; info->ata_status.error = sense[idx+3]; if (info->ata_status.extend) { info->ata_status.sector_count = (sense[idx+4] << 8) | sense[idx+5]; info->ata_status.lba = ((uint64_t)sense[idx+7]) | ((uint64_t)sense[idx+6]<<8) | ((uint64_t)sense[idx+9]<<16) | ((uint64_t)sense[idx+8]<<24) | ((uint64_t)sense[idx+11]<<32) | ((uint64_t)sense[idx+10]<<40); } else { info->ata_status.sector_count = sense[idx+4]; info->ata_status.lba = sense[idx+7] | (sense[idx+9]<<8) | (sense[idx+11]<<16); } info->ata_status.device = sense[idx+12]; info->ata_status.status = sense[idx+13]; } break; case 0x0A: // Progress indication break; case 0x0B: // User data segment referral break; case 0x80: // Vendor Unique Unit Error if (desc_len == 0x02) { info->vendor_unique_error = get_uint16(sense, idx+2); } break; } } return true; } bool scsi_parse_sense(unsigned char *sense, int sense_len, sense_info_t *info) { uint8_t response_code = sense[0] & 0x7F; memset(info, 0, sizeof(*info)); if (response_code != 0x70 && response_code != 0x71 && response_code != 0x72 && response_code != 0x73) return false; if (response_code == 0x70 || response_code == 0x71) info->is_fixed = true; if (response_code == 0x70 || response_code == 0x72) info->is_current = true; if (info->is_fixed) return parse_sense_fixed(sense, sense_len, info); else return parse_sense_descriptor(sense, sense_len, info); } diskscan-0.21/libscsicmd/src/smartdb/000077500000000000000000000000001456470715000176035ustar00rootroot00000000000000diskscan-0.21/libscsicmd/src/smartdb/smartdb.c000066400000000000000000000007551456470715000214120ustar00rootroot00000000000000#include "smartdb.h" #include const smart_attr_t *smart_attr_for_id(const smart_table_t *table, uint8_t id) { int i; for (i = 0; i < table->num_attrs; i++) { if (table->attrs[i].id == id) return &table->attrs[i]; } return NULL; } const smart_attr_t *smart_attr_for_type(const smart_table_t *table, smart_attr_type_e attr_type) { int i; for (i = 0; i < table->num_attrs; i++) { if (table->attrs[i].type == attr_type) return &table->attrs[i]; } return NULL; } diskscan-0.21/libscsicmd/src/smartdb/smartdb.xml000066400000000000000000000066141456470715000217700ustar00rootroot00000000000000 Raw Read Error Rate Throughput Performance Spin Up Time Start/Stop Count Reallocated Sectors Count Seek Error Rate Seek Time Performance Power On Hours Spin Retry Count Device Power Cycle Count G Sense Error Rate Power Off Retract Count Load/Unload Cycle Count Temperature Reallocation Event Count Pending Sector Reallocation Count Off-Line Scan Uncorrecable Sector Count CRC Error Count Total LBAs Written Multi-zone Error Rate Drive Calibration Retry Count Free Fall Sensor Total LBAs Read Head Flying Hours Hardware ECC Recovered Read Soft Error Rate 1 Raw Read Error Rate dec48 2 Throughput Performance 3 Spin Up Time 4 Start/Stop Count 5 Reallocated Sectors Count 7 Seek Error Rate 8 Seek Time Performance 9 Power On Hours 10 Spin Retry Count 11 Drive Calibration Retry Count 12 Device Power Cycle Count 13 Read Soft Error Rate 191 G Sense Error Rate 192 Power Off Retract Count 193 Load/Unload Cycle Count 194 Temperature 150 195 Hardware ECC Recovered 196 Reallocation Event Count 197 Pending Sector Reallocation Count 198 Off-Line Scan Uncorrecable Sector Count 199 CRC Error Count 200 Multi-zone Error Rate 240 Head Flying Hours 241 Total LBAs Written 242 Total LBAs Read 254 Free Fall Sensor diskscan-0.21/libscsicmd/src/smartdb/smartdb_gen.c000066400000000000000000000060071456470715000222370ustar00rootroot00000000000000#include "smartdb.h" static const smart_table_t defaults = { .num_attrs = 26, .attrs = { {.id=1, .type=SMART_ATTR_TYPE_NONE, .name="Raw Read Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=2, .type=SMART_ATTR_TYPE_NONE, .name="Throughput Performance", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=3, .type=SMART_ATTR_TYPE_NONE, .name="Spin Up Time", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=4, .type=SMART_ATTR_TYPE_NONE, .name="Start/Stop Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=5, .type=SMART_ATTR_TYPE_REALLOC, .name="Reallocated Sectors Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=7, .type=SMART_ATTR_TYPE_NONE, .name="Seek Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=8, .type=SMART_ATTR_TYPE_NONE, .name="Seek Time Performance", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=9, .type=SMART_ATTR_TYPE_POH, .name="Power On Hours", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=10, .type=SMART_ATTR_TYPE_NONE, .name="Spin Retry Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=11, .type=SMART_ATTR_TYPE_NONE, .name="Drive Calibration Retry Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=12, .type=SMART_ATTR_TYPE_NONE, .name="Device Power Cycle Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=13, .type=SMART_ATTR_TYPE_NONE, .name="Read Soft Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=191, .type=SMART_ATTR_TYPE_NONE, .name="G Sense Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=192, .type=SMART_ATTR_TYPE_NONE, .name="Power Off Retract Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=193, .type=SMART_ATTR_TYPE_NONE, .name="Load/Unload Cycle Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=194, .type=SMART_ATTR_TYPE_TEMP, .name="Temperature", .raw=SMART_ATTR_RAW_DEC48, .offset=150}, {.id=195, .type=SMART_ATTR_TYPE_NONE, .name="Hardware ECC Recovered", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=196, .type=SMART_ATTR_TYPE_NONE, .name="Reallocation Event Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=197, .type=SMART_ATTR_TYPE_REALLOC_PENDING, .name="Pending Sector Reallocation Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=198, .type=SMART_ATTR_TYPE_NONE, .name="Off-Line Scan Uncorrecable Sector Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=199, .type=SMART_ATTR_TYPE_CRC_ERRORS, .name="CRC Error Count", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=200, .type=SMART_ATTR_TYPE_NONE, .name="Multi-zone Error Rate", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=240, .type=SMART_ATTR_TYPE_NONE, .name="Head Flying Hours", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=241, .type=SMART_ATTR_TYPE_NONE, .name="Total LBAs Written", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=242, .type=SMART_ATTR_TYPE_NONE, .name="Total LBAs Read", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, {.id=254, .type=SMART_ATTR_TYPE_NONE, .name="Free Fall Sensor", .raw=SMART_ATTR_RAW_DEC48, .offset=-1}, } }; const smart_table_t * smart_table_for_disk(const char *vendor, const char *model, const char *firmware) { (void)vendor; (void)model; (void)firmware; return &defaults; } diskscan-0.21/libscsicmd/src/smartdb/smartdb_gen_c.py000077500000000000000000000057641456470715000227630ustar00rootroot00000000000000#!/usr/bin/env python import xml.etree.ElementTree as ET import sys tree = ET.parse(sys.argv[1]) root = tree.getroot() assert root.tag == 'smartdb' names = {} defaults = {} raw_types = { 'hex48': 'SMART_ATTR_RAW_HEX48', 'dec48': 'SMART_ATTR_RAW_DEC48', } raw_type_default = 'dec48' def raw_type_to_enum(raw): return raw_types.get(raw) attr_code = { 'none': 'SMART_ATTR_TYPE_NONE', 'poh': 'SMART_ATTR_TYPE_POH', 'temperature': 'SMART_ATTR_TYPE_TEMP', 'reallocations': 'SMART_ATTR_TYPE_REALLOC', 'pending_reallocations': 'SMART_ATTR_TYPE_REALLOC_PENDING', 'crc_count': 'SMART_ATTR_TYPE_CRC_ERRORS', } attr_code_default = 'none' def attr_code_to_enum(code): try: return attr_code[code] except KeyError: sys.stderr.write('Cannot find key "%s" in the known attribute code list: %s\n' % (code, attr_code.keys())) raise def validate_name(c, root): assert root.tag == 'name' name = root.text.strip() assert len(name) > 0 for child in root: assert False, 'node cant have a child' assert name not in names names[name] = root.get('type', attr_code_default) def validate_attr(d, root): assert root.tag == 'attr' aid = None name = None tempoffset = -1 raw = raw_type_default code = attr_code_default for child in root: assert child.tag in ('id', 'name', 'raw', 'tempoffset') if child.tag == 'id': val = int(child.text) assert val > 0 assert val <= 255 aid = val elif child.tag == 'name': val = child.text.strip() assert val in names name = val code = names.get(name) elif child.tag == 'raw': val = child.text.strip() assert val in list(raw_types.keys()) raw = val elif child.tag == 'tempoffset': val = int(child.text) assert val > 0 and val < 255 tempoffset = val d[aid] = (aid, name, raw, code, tempoffset) nodes = { 'names': validate_name, 'default': validate_attr, } for child in root: if child.tag not in list(nodes.keys()): raise 'tag %s is unknown at smartdb level' % child.tag vfunc = nodes.get(child.tag) for subchild in child: vfunc(defaults, subchild) print('#include "smartdb.h"') print('static const smart_table_t defaults = {') print('.num_attrs = %d,' % len(defaults)) print('.attrs = {') keys = list(defaults.keys()) keys.sort() for aid in keys: attr = defaults[aid] name = attr[1] raw = raw_type_to_enum(attr[2]) atype = attr_code_to_enum(attr[3]) tempoffset = attr[4] print('{.id=%d, .type=%s, .name="%s", .raw=%s, .offset=%d},' % (aid, atype, name, raw, tempoffset)) print('}') print('};') print('const smart_table_t * smart_table_for_disk(const char *vendor, const char *model, const char *firmware)') print('{') print('(void)vendor;') print('(void)model;') print('(void)firmware;') print('return &defaults;') print('}') diskscan-0.21/libscsicmd/src/str_map.c000066400000000000000000000016131456470715000177610ustar00rootroot00000000000000#include "scsicmd.h" #include const char *sense_key_to_name(enum sense_key_e sense_key) { #undef SENSE_KEY_MAP switch (sense_key) { #define SENSE_KEY_MAP(_name_, _val_) \ case _val_: return #_name_ ; SENSE_KEY_LIST } #undef SENSE_KEY_MAP return "Unknown sense key"; } const char *asc_num_to_name(uint8_t asc, uint8_t ascq) { static char msg[64]; uint16_t asc_full = asc<<8 | ascq; switch (asc_full) { #define SENSE_CODE_KEYED(_asc_, _fmt_) #define SENSE_CODE(_asc_, _ascq_, _msg_) case _asc_<<8 | _ascq_: return _msg_; ASC_NUM_LIST #undef SENSE_CODE #undef SENSE_CODE_KEYED } #define SENSE_CODE_KEYED(_asc_, _fmt_) if (asc == _asc_) { snprintf(msg, sizeof(msg), _fmt_, ascq); return msg; } #define SENSE_CODE(_asc_, _ascq_, _msg_) ASC_NUM_LIST #undef SENSE_CODE #undef SENSE_CODE_KEYED snprintf(msg, sizeof(msg), "UNKNOWN ASC/ASCQ (%02Xh/%02Xh)", asc, ascq); return msg; } diskscan-0.21/libscsicmd/structs/000077500000000000000000000000001456470715000170675ustar00rootroot00000000000000diskscan-0.21/libscsicmd/structs/asc-num-to-list000077500000000000000000000014101456470715000217450ustar00rootroot00000000000000#!/usr/bin/env python import sys def nn_str(name): return name.replace('NN', '%u') # Skip the header for line in sys.stdin: if line[0] == '-': break # Read the raw data print('#ifndef LIBSCSICMD_ASC_NUM_LIST_H') print('#define LIBSCSICMD_ASC_NUM_LIST_H') print('#define ASC_NUM_LIST \\') for line in sys.stdin: line = line.strip() asc = int(line[0:2], 16) ascq_str = line[4:6] if ascq_str == 'NN': ascq = 'NN' else: ascq = int(ascq_str, 16) name = line[24:] if name == '': continue if ascq == 'NN': name_nn = nn_str(name) print('SENSE_CODE_KEYED(0x%x, "%s") \\' % (asc, name_nn)) else: print('SENSE_CODE(0x%x, 0x%x, "%s") \\' % (asc, ascq, name)) print() print('#endif') diskscan-0.21/libscsicmd/structs/asc-num.txt000066400000000000000000001257341456470715000212070ustar00rootroot00000000000000File: ASC-NUM.TXT SCSI ASC/ASCQ Assignments Numeric Sorted Listing as of 1/03/15 D - Direct Access Block Device (SBC-4) device column key .Z - Host Managed Zoned Block Device (ZBC) ------------------- . T - Sequential Access Device (SSC-5) blank = reserved . P - Processor Device (SPC-2) not blank = allowed . .R - C/DVD Device (MMC-6) . . O - Optical Memory Block Device (SBC) . . M - Media Changer Device (SMC-3) . . .A - Storage Array Device (SCC-2) . . . E - SCSI Enclosure Services device (SES-3) . . . B - Simplified Direct-Access (Reduced Block) device (RBC) . . . .K - Optical Card Reader/Writer device (OCRW) . . . . V - Automation/Device Interface device (ADC-4) . . . . F - Object-based Storage Device (OSD-2) ASC/ASCQ DZTPROMAEBKVF Description -------- ------------- ---------------------------------------------------- 00h/00h DZTPROMAEBKVF NO ADDITIONAL SENSE INFORMATION 00h/01h T FILEMARK DETECTED 00h/02h T END-OF-PARTITION/MEDIUM DETECTED 00h/03h T SETMARK DETECTED 00h/04h T BEGINNING-OF-PARTITION/MEDIUM DETECTED 00h/05h T END-OF-DATA DETECTED 00h/06h DZTPROMAEBKVF I/O PROCESS TERMINATED 00h/07h T PROGRAMMABLE EARLY WARNING DETECTED 00h/11h R AUDIO PLAY OPERATION IN PROGRESS 00h/12h R AUDIO PLAY OPERATION PAUSED 00h/13h R AUDIO PLAY OPERATION SUCCESSFULLY COMPLETED 00h/14h R AUDIO PLAY OPERATION STOPPED DUE TO ERROR 00h/15h R NO CURRENT AUDIO STATUS TO RETURN 00h/16h DZTPROMAEBKVF OPERATION IN PROGRESS 00h/17h DZT ROMAEBKVF CLEANING REQUESTED 00h/18h T ERASE OPERATION IN PROGRESS 00h/19h T LOCATE OPERATION IN PROGRESS 00h/1Ah T REWIND OPERATION IN PROGRESS 00h/1Bh T SET CAPACITY OPERATION IN PROGRESS 00h/1Ch T VERIFY OPERATION IN PROGRESS 00h/1Dh DZT B ATA PASS THROUGH INFORMATION AVAILABLE 00h/1Eh DZT R MAEBKV CONFLICTING SA CREATION REQUEST 00h/1Fh DZT B LOGICAL UNIT TRANSITIONING TO ANOTHER POWER CONDITION 00h/20h DZTP B EXTENDED COPY INFORMATION AVAILABLE 00h/21h DZ ATOMIC COMMAND ABORTED DUE TO ACA 01h/00h DZ O BK NO INDEX/SECTOR SIGNAL 02h/00h DZ RO BK NO SEEK COMPLETE 03h/00h DZT O BK PERIPHERAL DEVICE WRITE FAULT 03h/01h T NO WRITE CURRENT 03h/02h T EXCESSIVE WRITE ERRORS 04h/00h DZTPROMAEBKVF LOGICAL UNIT NOT READY, CAUSE NOT REPORTABLE 04h/01h DZTPROMAEBKVF LOGICAL UNIT IS IN PROCESS OF BECOMING READY 04h/02h DZTPROMAEBKVF LOGICAL UNIT NOT READY, INITIALIZING COMMAND REQUIRED 04h/03h DZTPROMAEBKVF LOGICAL UNIT NOT READY, MANUAL INTERVENTION REQUIRED 04h/04h DZT RO B LOGICAL UNIT NOT READY, FORMAT IN PROGRESS 04h/05h DZT O A BK F LOGICAL UNIT NOT READY, REBUILD IN PROGRESS 04h/06h DZT O A BK LOGICAL UNIT NOT READY, RECALCULATION IN PROGRESS 04h/07h DZTPROMAEBKVF LOGICAL UNIT NOT READY, OPERATION IN PROGRESS 04h/08h R LOGICAL UNIT NOT READY, LONG WRITE IN PROGRESS 04h/09h DZTPROMAEBKVF LOGICAL UNIT NOT READY, SELF-TEST IN PROGRESS 04h/0Ah DZTPROMAEBKVF LOGICAL UNIT NOT ACCESSIBLE, ASYMMETRIC ACCESS STATE TRANSITION 04h/0Bh DZTPROMAEBKVF LOGICAL UNIT NOT ACCESSIBLE, TARGET PORT IN STANDBY STATE 04h/0Ch DZTPROMAEBKVF LOGICAL UNIT NOT ACCESSIBLE, TARGET PORT IN UNAVAILABLE STATE 04h/0Dh F LOGICAL UNIT NOT READY, STRUCTURE CHECK REQUIRED 04h/0Eh DZT R MAEBKVF LOGICAL UNIT NOT READY, SECURITY SESSION IN PROGRESS 04h/10h DZT ROM B LOGICAL UNIT NOT READY, AUXILIARY MEMORY NOT ACCESSIBLE 04h/11h DZT RO AEB VF LOGICAL UNIT NOT READY, NOTIFY (ENABLE SPINUP) REQUIRED 04h/12h M V LOGICAL UNIT NOT READY, OFFLINE 04h/13h DZT R MAEBKV LOGICAL UNIT NOT READY, SA CREATION IN PROGRESS 04h/14h DZ B LOGICAL UNIT NOT READY, SPACE ALLOCATION IN PROGRESS 04h/15h M LOGICAL UNIT NOT READY, ROBOTICS DISABLED 04h/16h M LOGICAL UNIT NOT READY, CONFIGURATION REQUIRED 04h/17h M LOGICAL UNIT NOT READY, CALIBRATION REQUIRED 04h/18h M LOGICAL UNIT NOT READY, A DOOR IS OPEN 04h/19h M LOGICAL UNIT NOT READY, OPERATING IN SEQUENTIAL MODE 04h/1Ah DZ B LOGICAL UNIT NOT READY, START STOP UNIT COMMAND IN PROGRESS 04h/1Bh DZ B LOGICAL UNIT NOT READY, SANITIZE IN PROGRESS 04h/1Ch DZT MAEB LOGICAL UNIT NOT READY, ADDITIONAL POWER USE NOT YET GRANTED 04h/1Dh DZ LOGICAL UNIT NOT READY, CONFIGURATION IN PROGRESS 04h/1Eh DZ LOGICAL UNIT NOT READY, MICROCODE ACTIVATION REQUIRED 04h/1Fh DZTPROMAEBKVF LOGICAL UNIT NOT READY, MICROCODE DOWNLOAD REQUIRED 04h/20h DZTPROMAEBKVF LOGICAL UNIT NOT READY, LOGICAL UNIT RESET REQUIRED 04h/21h DZTPROMAEBKVF LOGICAL UNIT NOT READY, HARD RESET REQUIRED 04h/22h DZTPROMAEBKVF LOGICAL UNIT NOT READY, POWER CYCLE REQUIRED 05h/00h DZT ROMAEBKVF LOGICAL UNIT DOES NOT RESPOND TO SELECTION 06h/00h DZ ROM BK NO REFERENCE POSITION FOUND 07h/00h DZT ROM BK MULTIPLE PERIPHERAL DEVICES SELECTED 08h/00h DZT ROMAEBKVF LOGICAL UNIT COMMUNICATION FAILURE 08h/01h DZT ROMAEBKVF LOGICAL UNIT COMMUNICATION TIME-OUT 08h/02h DZT ROMAEBKVF LOGICAL UNIT COMMUNICATION PARITY ERROR 08h/03h DZT ROM BK LOGICAL UNIT COMMUNICATION CRC ERROR (ULTRA-DMA/32) 08h/04h DZTPRO K UNREACHABLE COPY TARGET 09h/00h DZT RO B TRACK FOLLOWING ERROR 09h/01h RO K TRACKING SERVO FAILURE 09h/02h RO K FOCUS SERVO FAILURE 09h/03h RO SPINDLE SERVO FAILURE 09h/04h DZT RO B HEAD SELECT FAULT 09h/05h DZT RO B VIBRATION INDUCED TRACKING ERROR 0Ah/00h DZTPROMAEBKVF ERROR LOG OVERFLOW 0Bh/00h DZTPROMAEBKVF WARNING 0Bh/01h DZTPROMAEBKVF WARNING - SPECIFIED TEMPERATURE EXCEEDED 0Bh/02h DZTPROMAEBKVF WARNING - ENCLOSURE DEGRADED 0Bh/03h DZTPROMAEBKVF WARNING - BACKGROUND SELF-TEST FAILED 0Bh/04h DZTPRO AEBKVF WARNING - BACKGROUND PRE-SCAN DETECTED MEDIUM ERROR 0Bh/05h DZTPRO AEBKVF WARNING - BACKGROUND MEDIUM SCAN DETECTED MEDIUM ERROR 0Bh/06h DZTPROMAEBKVF WARNING - NON-VOLATILE CACHE NOW VOLATILE 0Bh/07h DZTPROMAEBKVF WARNING - DEGRADED POWER TO NON-VOLATILE CACHE 0Bh/08h DZTPROMAEBKVF WARNING - POWER LOSS EXPECTED 0Bh/09h DZ WARNING - DEVICE STATISTICS NOTIFICATION ACTIVE 0Bh/0Ah DZTPROMAEBKV WARNING - HIGH CRITICAL TEMPERATURE LIMIT EXCEEDED 0Bh/0Bh DZTPROMAEBKV WARNING - LOW CRITICAL TEMPERATURE LIMIT EXCEEDED 0Bh/0Ch DZTPROMAEBKV WARNING - HIGH OPERATING TEMPERATURE LIMIT EXCEEDED 0Bh/0Dh DZTPROMAEBKV WARNING - LOW OPERATING TEMPERATURE LIMIT EXCEEDED 0Bh/0Eh DZTPROMAEBKV WARNING - HIGH CRITICAL HUMIDITY LIMIT EXCEEDED 0Bh/0Fh DZTPROMAEBKV WARNING - LOW CRITICAL HUMIDITY LIMIT EXCEEDED 0Bh/10h DZTPROMAEBKV WARNING - HIGH OPERATING HUMIDITY LIMIT EXCEEDED 0Bh/11h DZTPROMAEBKV WARNING - LOW OPERATING HUMIDITY LIMIT EXCEEDED 0Ch/00h T R WRITE ERROR 0Ch/01h K WRITE ERROR - RECOVERED WITH AUTO REALLOCATION 0Ch/02h DZ O BK WRITE ERROR - AUTO REALLOCATION FAILED 0Ch/03h DZ O BK WRITE ERROR - RECOMMEND REASSIGNMENT 0Ch/04h DZT O B COMPRESSION CHECK MISCOMPARE ERROR 0Ch/05h DZT O B DATA EXPANSION OCCURRED DURING COMPRESSION 0Ch/06h DZT O B BLOCK NOT COMPRESSIBLE 0Ch/07h R WRITE ERROR - RECOVERY NEEDED 0Ch/08h R WRITE ERROR - RECOVERY FAILED 0Ch/09h R WRITE ERROR - LOSS OF STREAMING 0Ch/0Ah R WRITE ERROR - PADDING BLOCKS ADDED 0Ch/0Bh DZT ROM B AUXILIARY MEMORY WRITE ERROR 0Ch/0Ch DZTPRO AEBKVF WRITE ERROR - UNEXPECTED UNSOLICITED DATA 0Ch/0Dh DZTPRO AEBKVF WRITE ERROR - NOT ENOUGH UNSOLICITED DATA 0Ch/0Eh DZT O BK MULTIPLE WRITE ERRORS 0Ch/0Fh R DEFECTS IN ERROR WINDOW 0Ch/10h DZ INCOMPLETE MULTIPLE ATOMIC WRITE OPERATIONS 0Dh/00h DZTPRO A K ERROR DETECTED BY THIRD PARTY TEMPORARY INITIATOR 0Dh/01h DZTPRO A K THIRD PARTY DEVICE FAILURE 0Dh/02h DZTPRO A K COPY TARGET DEVICE NOT REACHABLE 0Dh/03h DZTPRO A K INCORRECT COPY TARGET DEVICE TYPE 0Dh/04h DZTPRO A K COPY TARGET DEVICE DATA UNDERRUN 0Dh/05h DZTPRO A K COPY TARGET DEVICE DATA OVERRUN 0Eh/00h DZTPROMAEBK F INVALID INFORMATION UNIT 0Eh/01h DZTPROMAEBK F INFORMATION UNIT TOO SHORT 0Eh/02h DZTPROMAEBK F INFORMATION UNIT TOO LONG 0Eh/03h DZTPR MAEBK F INVALID FIELD IN COMMAND INFORMATION UNIT 0Fh/00h 10h/00h DZ O BK ID CRC OR ECC ERROR 10h/01h DZT O LOGICAL BLOCK GUARD CHECK FAILED 10h/02h DZT O LOGICAL BLOCK APPLICATION TAG CHECK FAILED 10h/03h DZT O LOGICAL BLOCK REFERENCE TAG CHECK FAILED 10h/04h T LOGICAL BLOCK PROTECTION ERROR ON RECOVER BUFFERED DATA 10h/05h T LOGICAL BLOCK PROTECTION METHOD ERROR 11h/00h DZT RO BK UNRECOVERED READ ERROR 11h/01h DZT RO BK READ RETRIES EXHAUSTED 11h/02h DZT RO BK ERROR TOO LONG TO CORRECT 11h/03h DZT O BK MULTIPLE READ ERRORS 11h/04h DZ O BK UNRECOVERED READ ERROR - AUTO REALLOCATE FAILED 11h/05h RO B L-EC UNCORRECTABLE ERROR 11h/06h RO B CIRC UNRECOVERED ERROR 11h/07h O B DATA RE-SYNCHRONIZATION ERROR 11h/08h T INCOMPLETE BLOCK READ 11h/09h T NO GAP FOUND 11h/0Ah DZT O BK MISCORRECTED ERROR 11h/0Bh DZ O BK UNRECOVERED READ ERROR - RECOMMEND REASSIGNMENT 11h/0Ch DZ O BK UNRECOVERED READ ERROR - RECOMMEND REWRITE THE DATA 11h/0Dh DZT RO B DE-COMPRESSION CRC ERROR 11h/0Eh DZT RO B CANNOT DECOMPRESS USING DECLARED ALGORITHM 11h/0Fh R ERROR READING UPC/EAN NUMBER 11h/10h R ERROR READING ISRC NUMBER 11h/11h R READ ERROR - LOSS OF STREAMING 11h/12h DZT ROM B AUXILIARY MEMORY READ ERROR 11h/13h DZTPRO AEBKVF READ ERROR - FAILED RETRANSMISSION REQUEST 11h/14h DZ READ ERROR - LBA MARKED BAD BY APPLICATION CLIENT 11h/15h DZ WRITE AFTER SANITIZE REQUIRED 12h/00h DZ O BK ADDRESS MARK NOT FOUND FOR ID FIELD 13h/00h DZ O BK ADDRESS MARK NOT FOUND FOR DATA FIELD 14h/00h DZT RO BK RECORDED ENTITY NOT FOUND 14h/01h DZT RO BK RECORD NOT FOUND 14h/02h T FILEMARK OR SETMARK NOT FOUND 14h/03h T END-OF-DATA NOT FOUND 14h/04h T BLOCK SEQUENCE ERROR 14h/05h DZT O BK RECORD NOT FOUND - RECOMMEND REASSIGNMENT 14h/06h DZT O BK RECORD NOT FOUND - DATA AUTO-REALLOCATED 14h/07h T LOCATE OPERATION FAILURE 15h/00h DZT ROM BK RANDOM POSITIONING ERROR 15h/01h DZT ROM BK MECHANICAL POSITIONING ERROR 15h/02h DZT RO BK POSITIONING ERROR DETECTED BY READ OF MEDIUM 16h/00h DZ O BK DATA SYNCHRONIZATION MARK ERROR 16h/01h DZ O BK DATA SYNC ERROR - DATA REWRITTEN 16h/02h DZ O BK DATA SYNC ERROR - RECOMMEND REWRITE 16h/03h DZ O BK DATA SYNC ERROR - DATA AUTO-REALLOCATED 16h/04h DZ O BK DATA SYNC ERROR - RECOMMEND REASSIGNMENT 17h/00h DZT RO BK RECOVERED DATA WITH NO ERROR CORRECTION APPLIED 17h/01h DZT RO BK RECOVERED DATA WITH RETRIES 17h/02h DZT RO BK RECOVERED DATA WITH POSITIVE HEAD OFFSET 17h/03h DZT RO BK RECOVERED DATA WITH NEGATIVE HEAD OFFSET 17h/04h RO B RECOVERED DATA WITH RETRIES AND/OR CIRC APPLIED 17h/05h DZ RO BK RECOVERED DATA USING PREVIOUS SECTOR ID 17h/06h DZ O BK RECOVERED DATA WITHOUT ECC - DATA AUTO-REALLOCATED 17h/07h DZ RO BK RECOVERED DATA WITHOUT ECC - RECOMMEND REASSIGNMENT 17h/08h DZ RO BK RECOVERED DATA WITHOUT ECC - RECOMMEND REWRITE 17h/09h DZ RO BK RECOVERED DATA WITHOUT ECC - DATA REWRITTEN 18h/00h DZT RO BK RECOVERED DATA WITH ERROR CORRECTION APPLIED 18h/01h DZ RO BK RECOVERED DATA WITH ERROR CORR. & RETRIES APPLIED 18h/02h DZ RO BK RECOVERED DATA - DATA AUTO-REALLOCATED 18h/03h R RECOVERED DATA WITH CIRC 18h/04h R RECOVERED DATA WITH L-EC 18h/05h DZ RO BK RECOVERED DATA - RECOMMEND REASSIGNMENT 18h/06h DZ RO BK RECOVERED DATA - RECOMMEND REWRITE 18h/07h DZ O BK RECOVERED DATA WITH ECC - DATA REWRITTEN 18h/08h R RECOVERED DATA WITH LINKING 19h/00h DZ O K DEFECT LIST ERROR 19h/01h DZ O K DEFECT LIST NOT AVAILABLE 19h/02h DZ O K DEFECT LIST ERROR IN PRIMARY LIST 19h/03h DZ O K DEFECT LIST ERROR IN GROWN LIST 1Ah/00h DZTPROMAEBKVF PARAMETER LIST LENGTH ERROR 1Bh/00h DZTPROMAEBKVF SYNCHRONOUS DATA TRANSFER ERROR 1Ch/00h DZ O BK DEFECT LIST NOT FOUND 1Ch/01h DZ O BK PRIMARY DEFECT LIST NOT FOUND 1Ch/02h DZ O BK GROWN DEFECT LIST NOT FOUND 1Dh/00h DZT RO BK MISCOMPARE DURING VERIFY OPERATION 1Dh/01h DZ B MISCOMPARE VERIFY OF UNMAPPED LBA 1Eh/00h DZ O BK RECOVERED ID WITH ECC CORRECTION 1Fh/00h DZ O K PARTIAL DEFECT LIST TRANSFER 20h/00h DZTPROMAEBKVF INVALID COMMAND OPERATION CODE 20h/01h DZTPROMAEBK ACCESS DENIED - INITIATOR PENDING-ENROLLED 20h/02h DZTPROMAEBK ACCESS DENIED - NO ACCESS RIGHTS 20h/03h DZTPROMAEBK ACCESS DENIED - INVALID MGMT ID KEY 20h/04h T ILLEGAL COMMAND WHILE IN WRITE CAPABLE STATE 20h/05h T Obsolete 20h/06h T ILLEGAL COMMAND WHILE IN EXPLICIT ADDRESS MODE 20h/07h T ILLEGAL COMMAND WHILE IN IMPLICIT ADDRESS MODE 20h/08h DZTPROMAEBK ACCESS DENIED - ENROLLMENT CONFLICT 20h/09h DZTPROMAEBK ACCESS DENIED - INVALID LU IDENTIFIER 20h/0Ah DZTPROMAEBK ACCESS DENIED - INVALID PROXY TOKEN 20h/0Bh DZTPROMAEBK ACCESS DENIED - ACL LUN CONFLICT 20h/0Ch T ILLEGAL COMMAND WHEN NOT IN APPEND-ONLY MODE 21h/00h DZT RO BK LOGICAL BLOCK ADDRESS OUT OF RANGE 21h/01h DZT ROM BK INVALID ELEMENT ADDRESS 21h/02h R INVALID ADDRESS FOR WRITE 21h/03h R INVALID WRITE CROSSING LAYER JUMP 21h/04h DZ UNALIGNED WRITE COMMAND 21h/05h DZ WRITE BOUNDARY VIOLATION 21h/06h DZ ATTEMPT TO READ INVALID DATA 21h/07h DZ READ BOUNDARY VIOLATION 22h/00h DZ ILLEGAL FUNCTION (USE 20 00, 24 00, OR 26 00) 23h/00h DZTP B INVALID TOKEN OPERATION, CAUSE NOT REPORTABLE 23h/01h DZTP B INVALID TOKEN OPERATION, UNSUPPORTED TOKEN TYPE 23h/02h DZTP B INVALID TOKEN OPERATION, REMOTE TOKEN USAGE NOT SUPPORTED 23h/03h DZTP B INVALID TOKEN OPERATION, REMOTE ROD TOKEN CREATION NOT SUPPORTED 23h/04h DZTP B INVALID TOKEN OPERATION, TOKEN UNKNOWN 23h/05h DZTP B INVALID TOKEN OPERATION, TOKEN CORRUPT 23h/06h DZTP B INVALID TOKEN OPERATION, TOKEN REVOKED 23h/07h DZTP B INVALID TOKEN OPERATION, TOKEN EXPIRED 23h/08h DZTP B INVALID TOKEN OPERATION, TOKEN CANCELLED 23h/09h DZTP B INVALID TOKEN OPERATION, TOKEN DELETED 23h/0Ah DZTP B INVALID TOKEN OPERATION, INVALID TOKEN LENGTH 24h/00h DZTPROMAEBKVF INVALID FIELD IN CDB 24h/01h DZTPRO AEBKVF CDB DECRYPTION ERROR 24h/02h T Obsolete 24h/03h T Obsolete 24h/04h F SECURITY AUDIT VALUE FROZEN 24h/05h F SECURITY WORKING KEY FROZEN 24h/06h F NONCE NOT UNIQUE 24h/07h F NONCE TIMESTAMP OUT OF RANGE 24h/08h DZT R MAEBKV INVALID XCDB 25h/00h DZTPROMAEBKVF LOGICAL UNIT NOT SUPPORTED 26h/00h DZTPROMAEBKVF INVALID FIELD IN PARAMETER LIST 26h/01h DZTPROMAEBKVF PARAMETER NOT SUPPORTED 26h/02h DZTPROMAEBKVF PARAMETER VALUE INVALID 26h/03h DZTPROMAE K THRESHOLD PARAMETERS NOT SUPPORTED 26h/04h DZTPROMAEBKVF INVALID RELEASE OF PERSISTENT RESERVATION 26h/05h DZTPRO A BK DATA DECRYPTION ERROR 26h/06h DZTPRO K TOO MANY TARGET DESCRIPTORS 26h/07h DZTPRO K UNSUPPORTED TARGET DESCRIPTOR TYPE CODE 26h/08h DZTPRO K TOO MANY SEGMENT DESCRIPTORS 26h/09h DZTPRO K UNSUPPORTED SEGMENT DESCRIPTOR TYPE CODE 26h/0Ah DZTPRO K UNEXPECTED INEXACT SEGMENT 26h/0Bh DZTPRO K INLINE DATA LENGTH EXCEEDED 26h/0Ch DZTPRO K INVALID OPERATION FOR COPY SOURCE OR DESTINATION 26h/0Dh DZTPRO K COPY SEGMENT GRANULARITY VIOLATION 26h/0Eh DZTPROMAEBK INVALID PARAMETER WHILE PORT IS ENABLED 26h/0Fh F INVALID DATA-OUT BUFFER INTEGRITY CHECK VALUE 26h/10h T DATA DECRYPTION KEY FAIL LIMIT REACHED 26h/11h T INCOMPLETE KEY-ASSOCIATED DATA SET 26h/12h T VENDOR SPECIFIC KEY REFERENCE NOT FOUND 26h/13h D APPLICATION TAG MODE PAGE IS INVALID 27h/00h DZT RO BK WRITE PROTECTED 27h/01h DZT RO BK HARDWARE WRITE PROTECTED 27h/02h DZT RO BK LOGICAL UNIT SOFTWARE WRITE PROTECTED 27h/03h T R ASSOCIATED WRITE PROTECT 27h/04h T R PERSISTENT WRITE PROTECT 27h/05h T R PERMANENT WRITE PROTECT 27h/06h R F CONDITIONAL WRITE PROTECT 27h/07h DZ B SPACE ALLOCATION FAILED WRITE PROTECT 27h/08h DZ ZONE IS READ ONLY 28h/00h DZTPROMAEBKVF NOT READY TO READY CHANGE, MEDIUM MAY HAVE CHANGED 28h/01h DZT ROM B IMPORT OR EXPORT ELEMENT ACCESSED 28h/02h R FORMAT-LAYER MAY HAVE CHANGED 28h/03h M IMPORT/EXPORT ELEMENT ACCESSED, MEDIUM CHANGED 29h/00h DZTPROMAEBKVF POWER ON, RESET, OR BUS DEVICE RESET OCCURRED 29h/01h DZTPROMAEBKVF POWER ON OCCURRED 29h/02h DZTPROMAEBKVF SCSI BUS RESET OCCURRED 29h/03h DZTPROMAEBKVF BUS DEVICE RESET FUNCTION OCCURRED 29h/04h DZTPROMAEBKVF DEVICE INTERNAL RESET 29h/05h DZTPROMAEBKVF TRANSCEIVER MODE CHANGED TO SINGLE-ENDED 29h/06h DZTPROMAEBKVF TRANSCEIVER MODE CHANGED TO LVD 29h/07h DZTPROMAEBKVF I_T NEXUS LOSS OCCURRED 2Ah/00h DZT ROMAEBKVF PARAMETERS CHANGED 2Ah/01h DZT ROMAEBKVF MODE PARAMETERS CHANGED 2Ah/02h DZT ROMAE K LOG PARAMETERS CHANGED 2Ah/03h DZTPROMAE K RESERVATIONS PREEMPTED 2Ah/04h DZTPROMAE RESERVATIONS RELEASED 2Ah/05h DZTPROMAE REGISTRATIONS PREEMPTED 2Ah/06h DZTPROMAEBKVF ASYMMETRIC ACCESS STATE CHANGED 2Ah/07h DZTPROMAEBKVF IMPLICIT ASYMMETRIC ACCESS STATE TRANSITION FAILED 2Ah/08h DZT ROMAEBKVF PRIORITY CHANGED 2Ah/09h DZ CAPACITY DATA HAS CHANGED 2Ah/0Ah DZT ERROR HISTORY I_T NEXUS CLEARED 2Ah/0Bh DZT ERROR HISTORY SNAPSHOT RELEASED 2Ah/0Ch F ERROR RECOVERY ATTRIBUTES HAVE CHANGED 2Ah/0Dh T DATA ENCRYPTION CAPABILITIES CHANGED 2Ah/10h DZT M E V TIMESTAMP CHANGED 2Ah/11h T DATA ENCRYPTION PARAMETERS CHANGED BY ANOTHER I_T NEXUS 2Ah/12h T DATA ENCRYPTION PARAMETERS CHANGED BY VENDOR SPECIFIC EVENT 2Ah/13h T DATA ENCRYPTION KEY INSTANCE COUNTER HAS CHANGED 2Ah/14h DZT R MAEBKV SA CREATION CAPABILITIES DATA HAS CHANGED 2Ah/15h T M V MEDIUM REMOVAL PREVENTION PREEMPTED 2Bh/00h DZTPRO K COPY CANNOT EXECUTE SINCE HOST CANNOT DISCONNECT 2Ch/00h DZTPROMAEBKVF COMMAND SEQUENCE ERROR 2Ch/01h TOO MANY WINDOWS SPECIFIED 2Ch/02h INVALID COMBINATION OF WINDOWS SPECIFIED 2Ch/03h R CURRENT PROGRAM AREA IS NOT EMPTY 2Ch/04h R CURRENT PROGRAM AREA IS EMPTY 2Ch/05h B ILLEGAL POWER CONDITION REQUEST 2Ch/06h R PERSISTENT PREVENT CONFLICT 2Ch/07h DZTPROMAEBKVF PREVIOUS BUSY STATUS 2Ch/08h DZTPROMAEBKVF PREVIOUS TASK SET FULL STATUS 2Ch/09h DZTPROM EBKVF PREVIOUS RESERVATION CONFLICT STATUS 2Ch/0Ah F PARTITION OR COLLECTION CONTAINS USER OBJECTS 2Ch/0Bh T NOT RESERVED 2Ch/0Ch DZ ORWRITE GENERATION DOES NOT MATCH 2Ch/0Dh DZ RESET WRITE POINTER NOT ALLOWED 2Ch/0Eh DZ ZONE IS OFFLINE 2Dh/00h T OVERWRITE ERROR ON UPDATE IN PLACE 2Eh/00h DZ ROM B INSUFFICIENT TIME FOR OPERATION 2Eh/01h DZ OM B COMMAND TIMEOUT BEFORE PROCESSING 2Eh/02h DZ OM B COMMAND TIMEOUT DURING PROCESSING 2Eh/03h DZ OM B COMMAND TIMEOUT DURING PROCESSING DUE TO ERROR RECOVERY 2Fh/00h DZTPROMAEBKVF COMMANDS CLEARED BY ANOTHER INITIATOR 2Fh/01h DZ COMMANDS CLEARED BY POWER LOSS NOTIFICATION 2Fh/02h DZTPROMAEBKVF COMMANDS CLEARED BY DEVICE SERVER 2Fh/03h DZTPROMAEBKVF SOME COMMANDS CLEARED BY QUEUING LAYER EVENT 30h/00h DZT ROM BK INCOMPATIBLE MEDIUM INSTALLED 30h/01h DZT RO BK CANNOT READ MEDIUM - UNKNOWN FORMAT 30h/02h DZT RO BK CANNOT READ MEDIUM - INCOMPATIBLE FORMAT 30h/03h DZT R M K CLEANING CARTRIDGE INSTALLED 30h/04h DZT RO BK CANNOT WRITE MEDIUM - UNKNOWN FORMAT 30h/05h DZT RO BK CANNOT WRITE MEDIUM - INCOMPATIBLE FORMAT 30h/06h DZT RO B CANNOT FORMAT MEDIUM - INCOMPATIBLE MEDIUM 30h/07h DZT ROMAEBKVF CLEANING FAILURE 30h/08h R CANNOT WRITE - APPLICATION CODE MISMATCH 30h/09h R CURRENT SESSION NOT FIXATED FOR APPEND 30h/0Ah DZT RO AEBK CLEANING REQUEST REJECTED 30h/0Ch T WORM MEDIUM - OVERWRITE ATTEMPTED 30h/0Dh T WORM MEDIUM - INTEGRITY CHECK 30h/10h R MEDIUM NOT FORMATTED 30h/11h M INCOMPATIBLE VOLUME TYPE 30h/12h M INCOMPATIBLE VOLUME QUALIFIER 30h/13h M CLEANING VOLUME EXPIRED 31h/00h DZT RO BK MEDIUM FORMAT CORRUPTED 31h/01h DZ RO B FORMAT COMMAND FAILED 31h/02h R ZONED FORMATTING FAILED DUE TO SPARE LINKING 31h/03h DZ B SANITIZE COMMAND FAILED 32h/00h DZ O BK NO DEFECT SPARE LOCATION AVAILABLE 32h/01h DZ O BK DEFECT LIST UPDATE FAILURE 33h/00h T TAPE LENGTH ERROR 34h/00h DZTPROMAEBKVF ENCLOSURE FAILURE 35h/00h DZTPROMAEBKVF ENCLOSURE SERVICES FAILURE 35h/01h DZTPROMAEBKVF UNSUPPORTED ENCLOSURE FUNCTION 35h/02h DZTPROMAEBKVF ENCLOSURE SERVICES UNAVAILABLE 35h/03h DZTPROMAEBKVF ENCLOSURE SERVICES TRANSFER FAILURE 35h/04h DZTPROMAEBKVF ENCLOSURE SERVICES TRANSFER REFUSED 35h/05h DZT ROMAEBKVF ENCLOSURE SERVICES CHECKSUM ERROR 36h/00h RIBBON, INK, OR TONER FAILURE 37h/00h DZT ROMAEBKVF ROUNDED PARAMETER 38h/00h B EVENT STATUS NOTIFICATION 38h/02h B ESN - POWER MANAGEMENT CLASS EVENT 38h/04h B ESN - MEDIA CLASS EVENT 38h/06h B ESN - DEVICE BUSY CLASS EVENT 38h/07h DZ THIN PROVISIONING SOFT THRESHOLD REACHED 39h/00h DZT ROMAE K SAVING PARAMETERS NOT SUPPORTED 3Ah/00h DZT ROM BK MEDIUM NOT PRESENT 3Ah/01h DZT ROM BK MEDIUM NOT PRESENT - TRAY CLOSED 3Ah/02h DZT ROM BK MEDIUM NOT PRESENT - TRAY OPEN 3Ah/03h DZT ROM B MEDIUM NOT PRESENT - LOADABLE 3Ah/04h DZT RO B MEDIUM NOT PRESENT - MEDIUM AUXILIARY MEMORY ACCESSIBLE 3Bh/00h T SEQUENTIAL POSITIONING ERROR 3Bh/01h T TAPE POSITION ERROR AT BEGINNING-OF-MEDIUM 3Bh/02h T TAPE POSITION ERROR AT END-OF-MEDIUM 3Bh/03h TAPE OR ELECTRONIC VERTICAL FORMS UNIT NOT READY 3Bh/04h SLEW FAILURE 3Bh/05h PAPER JAM 3Bh/06h FAILED TO SENSE TOP-OF-FORM 3Bh/07h FAILED TO SENSE BOTTOM-OF-FORM 3Bh/08h T REPOSITION ERROR 3Bh/09h READ PAST END OF MEDIUM 3Bh/0Ah READ PAST BEGINNING OF MEDIUM 3Bh/0Bh POSITION PAST END OF MEDIUM 3Bh/0Ch T POSITION PAST BEGINNING OF MEDIUM 3Bh/0Dh DZT ROM BK MEDIUM DESTINATION ELEMENT FULL 3Bh/0Eh DZT ROM BK MEDIUM SOURCE ELEMENT EMPTY 3Bh/0Fh R END OF MEDIUM REACHED 3Bh/11h DZT ROM BK MEDIUM MAGAZINE NOT ACCESSIBLE 3Bh/12h DZT ROM BK MEDIUM MAGAZINE REMOVED 3Bh/13h DZT ROM BK MEDIUM MAGAZINE INSERTED 3Bh/14h DZT ROM BK MEDIUM MAGAZINE LOCKED 3Bh/15h DZT ROM BK MEDIUM MAGAZINE UNLOCKED 3Bh/16h R MECHANICAL POSITIONING OR CHANGER ERROR 3Bh/17h F READ PAST END OF USER OBJECT 3Bh/18h M ELEMENT DISABLED 3Bh/19h M ELEMENT ENABLED 3Bh/1Ah M DATA TRANSFER DEVICE REMOVED 3Bh/1Bh M DATA TRANSFER DEVICE INSERTED 3Bh/1Ch T TOO MANY LOGICAL OBJECTS ON PARTITION TO SUPPORT OPERATION 3Ch/00h 3Dh/00h DZTPROMAE K INVALID BITS IN IDENTIFY MESSAGE 3Eh/00h DZTPROMAEBKVF LOGICAL UNIT HAS NOT SELF-CONFIGURED YET 3Eh/01h DZTPROMAEBKVF LOGICAL UNIT FAILURE 3Eh/02h DZTPROMAEBKVF TIMEOUT ON LOGICAL UNIT 3Eh/03h DZTPROMAEBKVF LOGICAL UNIT FAILED SELF-TEST 3Eh/04h DZTPROMAEBKVF LOGICAL UNIT UNABLE TO UPDATE SELF-TEST LOG 3Fh/00h DZTPROMAEBKVF TARGET OPERATING CONDITIONS HAVE CHANGED 3Fh/01h DZTPROMAEBKVF MICROCODE HAS BEEN CHANGED 3Fh/02h DZTPROM BK CHANGED OPERATING DEFINITION 3Fh/03h DZTPROMAEBKVF INQUIRY DATA HAS CHANGED 3Fh/04h DZT ROMAEBK COMPONENT DEVICE ATTACHED 3Fh/05h DZT ROMAEBK DEVICE IDENTIFIER CHANGED 3Fh/06h DZT ROMAEB REDUNDANCY GROUP CREATED OR MODIFIED 3Fh/07h DZT ROMAEB REDUNDANCY GROUP DELETED 3Fh/08h DZT ROMAEB SPARE CREATED OR MODIFIED 3Fh/09h DZT ROMAEB SPARE DELETED 3Fh/0Ah DZT ROMAEBK VOLUME SET CREATED OR MODIFIED 3Fh/0Bh DZT ROMAEBK VOLUME SET DELETED 3Fh/0Ch DZT ROMAEBK VOLUME SET DEASSIGNED 3Fh/0Dh DZT ROMAEBK VOLUME SET REASSIGNED 3Fh/0Eh DZTPROMAE REPORTED LUNS DATA HAS CHANGED 3Fh/0Fh DZTPROMAEBKVF ECHO BUFFER OVERWRITTEN 3Fh/10h DZT ROM B MEDIUM LOADABLE 3Fh/11h DZT ROM B MEDIUM AUXILIARY MEMORY ACCESSIBLE 3Fh/12h DZTPR MAEBK F iSCSI IP ADDRESS ADDED 3Fh/13h DZTPR MAEBK F iSCSI IP ADDRESS REMOVED 3Fh/14h DZTPR MAEBK F iSCSI IP ADDRESS CHANGED 3Fh/15h DZTPR MAEBK INSPECT REFERRALS SENSE DESCRIPTORS 3Fh/16h DZTPROMAEBKVF MICROCODE HAS BEEN CHANGED WITHOUT RESET 40h/00h DZ RAM FAILURE (SHOULD USE 40 NN) 40h/NNh DZTPROMAEBKVF DIAGNOSTIC FAILURE ON COMPONENT NN (80h-FFh) 41h/00h DZ DATA PATH FAILURE (SHOULD USE 40 NN) 42h/00h DZ POWER-ON OR SELF-TEST FAILURE (SHOULD USE 40 NN) 43h/00h DZTPROMAEBKVF MESSAGE ERROR 44h/00h DZTPROMAEBKVF INTERNAL TARGET FAILURE 44h/01h DZTP MAEBKVF PERSISTENT RESERVATION INFORMATION LOST 44h/71h DZT B ATA DEVICE FAILED SET FEATURES 45h/00h DZTPROMAEBKVF SELECT OR RESELECT FAILURE 46h/00h DZTPROM BK UNSUCCESSFUL SOFT RESET 47h/00h DZTPROMAEBKVF SCSI PARITY ERROR 47h/01h DZTPROMAEBKVF DATA PHASE CRC ERROR DETECTED 47h/02h DZTPROMAEBKVF SCSI PARITY ERROR DETECTED DURING ST DATA PHASE 47h/03h DZTPROMAEBKVF INFORMATION UNIT iuCRC ERROR DETECTED 47h/04h DZTPROMAEBKVF ASYNCHRONOUS INFORMATION PROTECTION ERROR DETECTED 47h/05h DZTPROMAEBKVF PROTOCOL SERVICE CRC ERROR 47h/06h DZT MAEBKVF PHY TEST FUNCTION IN PROGRESS 47h/7Fh DZTPROMAEBK SOME COMMANDS CLEARED BY ISCSI PROTOCOL EVENT 48h/00h DZTPROMAEBKVF INITIATOR DETECTED ERROR MESSAGE RECEIVED 49h/00h DZTPROMAEBKVF INVALID MESSAGE ERROR 4Ah/00h DZTPROMAEBKVF COMMAND PHASE ERROR 4Bh/00h DZTPROMAEBKVF DATA PHASE ERROR 4Bh/01h DZTPROMAEBK INVALID TARGET PORT TRANSFER TAG RECEIVED 4Bh/02h DZTPROMAEBK TOO MUCH WRITE DATA 4Bh/03h DZTPROMAEBK ACK/NAK TIMEOUT 4Bh/04h DZTPROMAEBK NAK RECEIVED 4Bh/05h DZTPROMAEBK DATA OFFSET ERROR 4Bh/06h DZTPROMAEBK INITIATOR RESPONSE TIMEOUT 4Bh/07h DZTPROMAEBK F CONNECTION LOST 4Bh/08h DZTPROMAEBK F DATA-IN BUFFER OVERFLOW - DATA BUFFER SIZE 4Bh/09h DZTPROMAEBK F DATA-IN BUFFER OVERFLOW - DATA BUFFER DESCRIPTOR AREA 4Bh/0Ah DZTPROMAEBK F DATA-IN BUFFER ERROR 4Bh/0Bh DZTPROMAEBK F DATA-OUT BUFFER OVERFLOW - DATA BUFFER SIZE 4Bh/0Ch DZTPROMAEBK F DATA-OUT BUFFER OVERFLOW - DATA BUFFER DESCRIPTOR AREA 4Bh/0Dh DZTPROMAEBK F DATA-OUT BUFFER ERROR 4Bh/0Eh DZTPROMAEBK F PCIE FABRIC ERROR 4Bh/0Fh DZTPROMAEBK F PCIE COMPLETION TIMEOUT 4Bh/10h DZTPROMAEBK F PCIE COMPLETER ABORT 4Bh/11h DZTPROMAEBK F PCIE POISONED TLP RECEIVED 4Bh/12h DZTPROMAEBK F PCIE ECRC CHECK FAILED 4Bh/13h DZTPROMAEBK F PCIE UNSUPPORTED REQUEST 4Bh/14h DZTPROMAEBK F PCIE ACS VIOLATION 4Bh/15h DZTPROMAEBK F PCIE TLP PREFIX BLOCKED 4Ch/00h DZTPROMAEBKVF LOGICAL UNIT FAILED SELF-CONFIGURATION 4Dh/NNh DZTPROMAEBKVF TAGGED OVERLAPPED COMMANDS (NN = TASK TAG) 4Eh/00h DZTPROMAEBKVF OVERLAPPED COMMANDS ATTEMPTED 4Fh/00h 50h/00h T WRITE APPEND ERROR 50h/01h T WRITE APPEND POSITION ERROR 50h/02h T POSITION ERROR RELATED TO TIMING 51h/00h DZT RO ERASE FAILURE 51h/01h DZ R ERASE FAILURE - INCOMPLETE ERASE OPERATION DETECTED 52h/00h T CARTRIDGE FAULT 53h/00h DZT ROM BK MEDIA LOAD OR EJECT FAILED 53h/01h T UNLOAD TAPE FAILURE 53h/02h DZT ROM BK MEDIUM REMOVAL PREVENTED 53h/03h M MEDIUM REMOVAL PREVENTED BY DATA TRANSFER ELEMENT 53h/04h T MEDIUM THREAD OR UNTHREAD FAILURE 53h/05h M VOLUME IDENTIFIER INVALID 53h/06h M VOLUME IDENTIFIER MISSING 53h/07h M DUPLICATE VOLUME IDENTIFIER 53h/08h M ELEMENT STATUS UNKNOWN 53h/09h M DATA TRANSFER DEVICE ERROR - LOAD FAILED 53h/0Ah M DATA TRANSFER DEVICE ERROR - UNLOAD FAILED 53h/0Bh M DATA TRANSFER DEVICE ERROR - UNLOAD MISSING 53h/0Ch M DATA TRANSFER DEVICE ERROR - EJECT FAILED 53h/0Dh M DATA TRANSFER DEVICE ERROR - LIBRARY COMMUNICATION FAILED 54h/00h P SCSI TO HOST SYSTEM INTERFACE FAILURE 55h/00h P SYSTEM RESOURCE FAILURE 55h/01h DZ O BK SYSTEM BUFFER FULL 55h/02h DZTPROMAE K INSUFFICIENT RESERVATION RESOURCES 55h/03h DZTPROMAE K INSUFFICIENT RESOURCES 55h/04h DZTPROMAE K INSUFFICIENT REGISTRATION RESOURCES 55h/05h DZTPROMAEBK INSUFFICIENT ACCESS CONTROL RESOURCES 55h/06h DZT ROM B AUXILIARY MEMORY OUT OF SPACE 55h/07h F QUOTA ERROR 55h/08h T MAXIMUM NUMBER OF SUPPLEMENTAL DECRYPTION KEYS EXCEEDED 55h/09h M MEDIUM AUXILIARY MEMORY NOT ACCESSIBLE 55h/0Ah M DATA CURRENTLY UNAVAILABLE 55h/0Bh DZTPROMAEBKVF INSUFFICIENT POWER FOR OPERATION 55h/0Ch DZTP B INSUFFICIENT RESOURCES TO CREATE ROD 55h/0Dh DZTP B INSUFFICIENT RESOURCES TO CREATE ROD TOKEN 55h/0Eh DZ INSUFFICIENT ZONE RESOURCES 56h/00h 57h/00h R UNABLE TO RECOVER TABLE-OF-CONTENTS 58h/00h O GENERATION DOES NOT EXIST 59h/00h O UPDATED BLOCK READ 5Ah/00h DZTPRO BK OPERATOR REQUEST OR STATE CHANGE INPUT 5Ah/01h DZT ROM BK OPERATOR MEDIUM REMOVAL REQUEST 5Ah/02h DZT RO A BK OPERATOR SELECTED WRITE PROTECT 5Ah/03h DZT RO A BK OPERATOR SELECTED WRITE PERMIT 5Bh/00h DZTPROM K LOG EXCEPTION 5Bh/01h DZTPROM K THRESHOLD CONDITION MET 5Bh/02h DZTPROM K LOG COUNTER AT MAXIMUM 5Bh/03h DZTPROM K LOG LIST CODES EXHAUSTED 5Ch/00h DZ O RPL STATUS CHANGE 5Ch/01h DZ O SPINDLES SYNCHRONIZED 5Ch/02h DZ O SPINDLES NOT SYNCHRONIZED 5Dh/00h DZTPROMAEBKVF FAILURE PREDICTION THRESHOLD EXCEEDED 5Dh/01h R B MEDIA FAILURE PREDICTION THRESHOLD EXCEEDED 5Dh/02h R LOGICAL UNIT FAILURE PREDICTION THRESHOLD EXCEEDED 5Dh/03h R SPARE AREA EXHAUSTION PREDICTION THRESHOLD EXCEEDED 5Dh/10h DZ B HARDWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE 5Dh/11h DZ B HARDWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH 5Dh/12h DZ B HARDWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH 5Dh/13h DZ B HARDWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH 5Dh/14h DZ B HARDWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS 5Dh/15h DZ B HARDWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH 5Dh/16h DZ B HARDWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH 5Dh/17h DZ B HARDWARE IMPENDING FAILURE CHANNEL PARAMETRICS 5Dh/18h DZ B HARDWARE IMPENDING FAILURE CONTROLLER DETECTED 5Dh/19h DZ B HARDWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE 5Dh/1Ah DZ B HARDWARE IMPENDING FAILURE SEEK TIME PERFORMANCE 5Dh/1Bh DZ B HARDWARE IMPENDING FAILURE SPIN-UP RETRY COUNT 5Dh/1Ch DZ B HARDWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT 5Dh/20h DZ B CONTROLLER IMPENDING FAILURE GENERAL HARD DRIVE FAILURE 5Dh/21h DZ B CONTROLLER IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH 5Dh/22h DZ B CONTROLLER IMPENDING FAILURE DATA ERROR RATE TOO HIGH 5Dh/23h DZ B CONTROLLER IMPENDING FAILURE SEEK ERROR RATE TOO HIGH 5Dh/24h DZ B CONTROLLER IMPENDING FAILURE TOO MANY BLOCK REASSIGNS 5Dh/25h DZ B CONTROLLER IMPENDING FAILURE ACCESS TIMES TOO HIGH 5Dh/26h DZ B CONTROLLER IMPENDING FAILURE START UNIT TIMES TOO HIGH 5Dh/27h DZ B CONTROLLER IMPENDING FAILURE CHANNEL PARAMETRICS 5Dh/28h DZ B CONTROLLER IMPENDING FAILURE CONTROLLER DETECTED 5Dh/29h DZ B CONTROLLER IMPENDING FAILURE THROUGHPUT PERFORMANCE 5Dh/2Ah DZ B CONTROLLER IMPENDING FAILURE SEEK TIME PERFORMANCE 5Dh/2Bh DZ B CONTROLLER IMPENDING FAILURE SPIN-UP RETRY COUNT 5Dh/2Ch DZ B CONTROLLER IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT 5Dh/30h DZ B DATA CHANNEL IMPENDING FAILURE GENERAL HARD DRIVE FAILURE 5Dh/31h DZ B DATA CHANNEL IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH 5Dh/32h DZ B DATA CHANNEL IMPENDING FAILURE DATA ERROR RATE TOO HIGH 5Dh/33h DZ B DATA CHANNEL IMPENDING FAILURE SEEK ERROR RATE TOO HIGH 5Dh/34h DZ B DATA CHANNEL IMPENDING FAILURE TOO MANY BLOCK REASSIGNS 5Dh/35h DZ B DATA CHANNEL IMPENDING FAILURE ACCESS TIMES TOO HIGH 5Dh/36h DZ B DATA CHANNEL IMPENDING FAILURE START UNIT TIMES TOO HIGH 5Dh/37h DZ B DATA CHANNEL IMPENDING FAILURE CHANNEL PARAMETRICS 5Dh/38h DZ B DATA CHANNEL IMPENDING FAILURE CONTROLLER DETECTED 5Dh/39h DZ B DATA CHANNEL IMPENDING FAILURE THROUGHPUT PERFORMANCE 5Dh/3Ah DZ B DATA CHANNEL IMPENDING FAILURE SEEK TIME PERFORMANCE 5Dh/3Bh DZ B DATA CHANNEL IMPENDING FAILURE SPIN-UP RETRY COUNT 5Dh/3Ch DZ B DATA CHANNEL IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT 5Dh/40h DZ B SERVO IMPENDING FAILURE GENERAL HARD DRIVE FAILURE 5Dh/41h DZ B SERVO IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH 5Dh/42h DZ B SERVO IMPENDING FAILURE DATA ERROR RATE TOO HIGH 5Dh/43h DZ B SERVO IMPENDING FAILURE SEEK ERROR RATE TOO HIGH 5Dh/44h DZ B SERVO IMPENDING FAILURE TOO MANY BLOCK REASSIGNS 5Dh/45h DZ B SERVO IMPENDING FAILURE ACCESS TIMES TOO HIGH 5Dh/46h DZ B SERVO IMPENDING FAILURE START UNIT TIMES TOO HIGH 5Dh/47h DZ B SERVO IMPENDING FAILURE CHANNEL PARAMETRICS 5Dh/48h DZ B SERVO IMPENDING FAILURE CONTROLLER DETECTED 5Dh/49h DZ B SERVO IMPENDING FAILURE THROUGHPUT PERFORMANCE 5Dh/4Ah DZ B SERVO IMPENDING FAILURE SEEK TIME PERFORMANCE 5Dh/4Bh DZ B SERVO IMPENDING FAILURE SPIN-UP RETRY COUNT 5Dh/4Ch DZ B SERVO IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT 5Dh/50h DZ B SPINDLE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE 5Dh/51h DZ B SPINDLE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH 5Dh/52h DZ B SPINDLE IMPENDING FAILURE DATA ERROR RATE TOO HIGH 5Dh/53h DZ B SPINDLE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH 5Dh/54h DZ B SPINDLE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS 5Dh/55h DZ B SPINDLE IMPENDING FAILURE ACCESS TIMES TOO HIGH 5Dh/56h DZ B SPINDLE IMPENDING FAILURE START UNIT TIMES TOO HIGH 5Dh/57h DZ B SPINDLE IMPENDING FAILURE CHANNEL PARAMETRICS 5Dh/58h DZ B SPINDLE IMPENDING FAILURE CONTROLLER DETECTED 5Dh/59h DZ B SPINDLE IMPENDING FAILURE THROUGHPUT PERFORMANCE 5Dh/5Ah DZ B SPINDLE IMPENDING FAILURE SEEK TIME PERFORMANCE 5Dh/5Bh DZ B SPINDLE IMPENDING FAILURE SPIN-UP RETRY COUNT 5Dh/5Ch DZ B SPINDLE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT 5Dh/60h DZ B FIRMWARE IMPENDING FAILURE GENERAL HARD DRIVE FAILURE 5Dh/61h DZ B FIRMWARE IMPENDING FAILURE DRIVE ERROR RATE TOO HIGH 5Dh/62h DZ B FIRMWARE IMPENDING FAILURE DATA ERROR RATE TOO HIGH 5Dh/63h DZ B FIRMWARE IMPENDING FAILURE SEEK ERROR RATE TOO HIGH 5Dh/64h DZ B FIRMWARE IMPENDING FAILURE TOO MANY BLOCK REASSIGNS 5Dh/65h DZ B FIRMWARE IMPENDING FAILURE ACCESS TIMES TOO HIGH 5Dh/66h DZ B FIRMWARE IMPENDING FAILURE START UNIT TIMES TOO HIGH 5Dh/67h DZ B FIRMWARE IMPENDING FAILURE CHANNEL PARAMETRICS 5Dh/68h DZ B FIRMWARE IMPENDING FAILURE CONTROLLER DETECTED 5Dh/69h DZ B FIRMWARE IMPENDING FAILURE THROUGHPUT PERFORMANCE 5Dh/6Ah DZ B FIRMWARE IMPENDING FAILURE SEEK TIME PERFORMANCE 5Dh/6Bh DZ B FIRMWARE IMPENDING FAILURE SPIN-UP RETRY COUNT 5Dh/6Ch DZ B FIRMWARE IMPENDING FAILURE DRIVE CALIBRATION RETRY COUNT 5Dh/FFh DZTPROMAEBKVF FAILURE PREDICTION THRESHOLD EXCEEDED (FALSE) 5Eh/00h DZTPRO A K LOW POWER CONDITION ON 5Eh/01h DZTPRO A K IDLE CONDITION ACTIVATED BY TIMER 5Eh/02h DZTPRO A K STANDBY CONDITION ACTIVATED BY TIMER 5Eh/03h DZTPRO A K IDLE CONDITION ACTIVATED BY COMMAND 5Eh/04h DZTPRO A K STANDBY CONDITION ACTIVATED BY COMMAND 5Eh/05h DZTPRO A K IDLE_B CONDITION ACTIVATED BY TIMER 5Eh/06h DZTPRO A K IDLE_B CONDITION ACTIVATED BY COMMAND 5Eh/07h DZTPRO A K IDLE_C CONDITION ACTIVATED BY TIMER 5Eh/08h DZTPRO A K IDLE_C CONDITION ACTIVATED BY COMMAND 5Eh/09h DZTPRO A K STANDBY_Y CONDITION ACTIVATED BY TIMER 5Eh/0Ah DZTPRO A K STANDBY_Y CONDITION ACTIVATED BY COMMAND 5Eh/41h B POWER STATE CHANGE TO ACTIVE 5Eh/42h B POWER STATE CHANGE TO IDLE 5Eh/43h B POWER STATE CHANGE TO STANDBY 5Eh/45h B POWER STATE CHANGE TO SLEEP 5Eh/47h BK POWER STATE CHANGE TO DEVICE CONTROL 5Fh/00h 60h/00h LAMP FAILURE 61h/00h VIDEO ACQUISITION ERROR 61h/01h UNABLE TO ACQUIRE VIDEO 61h/02h OUT OF FOCUS 62h/00h SCAN HEAD POSITIONING ERROR 63h/00h R END OF USER AREA ENCOUNTERED ON THIS TRACK 63h/01h R PACKET DOES NOT FIT IN AVAILABLE SPACE 64h/00h R ILLEGAL MODE FOR THIS TRACK 64h/01h R INVALID PACKET SIZE 65h/00h DZTPROMAEBKVF VOLTAGE FAULT 66h/00h AUTOMATIC DOCUMENT FEEDER COVER UP 66h/01h AUTOMATIC DOCUMENT FEEDER LIFT UP 66h/02h DOCUMENT JAM IN AUTOMATIC DOCUMENT FEEDER 66h/03h DOCUMENT MISS FEED AUTOMATIC IN DOCUMENT FEEDER 67h/00h A CONFIGURATION FAILURE 67h/01h A CONFIGURATION OF INCAPABLE LOGICAL UNITS FAILED 67h/02h A ADD LOGICAL UNIT FAILED 67h/03h A MODIFICATION OF LOGICAL UNIT FAILED 67h/04h A EXCHANGE OF LOGICAL UNIT FAILED 67h/05h A REMOVE OF LOGICAL UNIT FAILED 67h/06h A ATTACHMENT OF LOGICAL UNIT FAILED 67h/07h A CREATION OF LOGICAL UNIT FAILED 67h/08h A ASSIGN FAILURE OCCURRED 67h/09h A MULTIPLY ASSIGNED LOGICAL UNIT 67h/0Ah DZTPROMAEBKVF SET TARGET PORT GROUPS COMMAND FAILED 67h/0Bh DZT B ATA DEVICE FEATURE NOT ENABLED 68h/00h A LOGICAL UNIT NOT CONFIGURED 68h/01h DZ SUBSIDIARY LOGICAL UNIT NOT CONFIGURED 69h/00h A DATA LOSS ON LOGICAL UNIT 69h/01h A MULTIPLE LOGICAL UNIT FAILURES 69h/02h A PARITY/DATA MISMATCH 6Ah/00h A INFORMATIONAL, REFER TO LOG 6Bh/00h A STATE CHANGE HAS OCCURRED 6Bh/01h A REDUNDANCY LEVEL GOT BETTER 6Bh/02h A REDUNDANCY LEVEL GOT WORSE 6Ch/00h A REBUILD FAILURE OCCURRED 6Dh/00h A RECALCULATE FAILURE OCCURRED 6Eh/00h A COMMAND TO LOGICAL UNIT FAILED 6Fh/00h R COPY PROTECTION KEY EXCHANGE FAILURE - AUTHENTICATION FAILURE 6Fh/01h R COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT PRESENT 6Fh/02h R COPY PROTECTION KEY EXCHANGE FAILURE - KEY NOT ESTABLISHED 6Fh/03h R READ OF SCRAMBLED SECTOR WITHOUT AUTHENTICATION 6Fh/04h R MEDIA REGION CODE IS MISMATCHED TO LOGICAL UNIT REGION 6Fh/05h R DRIVE REGION MUST BE PERMANENT/REGION RESET COUNT ERROR 6Fh/06h R INSUFFICIENT BLOCK COUNT FOR BINDING NONCE RECORDING 6Fh/07h R CONFLICT IN BINDING NONCE RECORDING 70h/NNh T DECOMPRESSION EXCEPTION SHORT ALGORITHM ID OF NN 71h/00h T DECOMPRESSION EXCEPTION LONG ALGORITHM ID 72h/00h R SESSION FIXATION ERROR 72h/01h R SESSION FIXATION ERROR WRITING LEAD-IN 72h/02h R SESSION FIXATION ERROR WRITING LEAD-OUT 72h/03h R SESSION FIXATION ERROR - INCOMPLETE TRACK IN SESSION 72h/04h R EMPTY OR PARTIALLY WRITTEN RESERVED TRACK 72h/05h R NO MORE TRACK RESERVATIONS ALLOWED 72h/06h R RMZ EXTENSION IS NOT ALLOWED 72h/07h R NO MORE TEST ZONE EXTENSIONS ARE ALLOWED 73h/00h R CD CONTROL ERROR 73h/01h R POWER CALIBRATION AREA ALMOST FULL 73h/02h R POWER CALIBRATION AREA IS FULL 73h/03h R POWER CALIBRATION AREA ERROR 73h/04h R PROGRAM MEMORY AREA UPDATE FAILURE 73h/05h R PROGRAM MEMORY AREA IS FULL 73h/06h R RMA/PMA IS ALMOST FULL 73h/10h R CURRENT POWER CALIBRATION AREA ALMOST FULL 73h/11h R CURRENT POWER CALIBRATION AREA IS FULL 73h/17h R RDZ IS FULL 74h/00h T SECURITY ERROR 74h/01h T UNABLE TO DECRYPT DATA 74h/02h T UNENCRYPTED DATA ENCOUNTERED WHILE DECRYPTING 74h/03h T INCORRECT DATA ENCRYPTION KEY 74h/04h T CRYPTOGRAPHIC INTEGRITY VALIDATION FAILED 74h/05h T ERROR DECRYPTING DATA 74h/06h T UNKNOWN SIGNATURE VERIFICATION KEY 74h/07h T ENCRYPTION PARAMETERS NOT USEABLE 74h/08h DZT R M E VF DIGITAL SIGNATURE VALIDATION FAILURE 74h/09h T ENCRYPTION MODE MISMATCH ON READ 74h/0Ah T ENCRYPTED BLOCK NOT RAW READ ENABLED 74h/0Bh T INCORRECT ENCRYPTION PARAMETERS 74h/0Ch DZT R MAEBKV UNABLE TO DECRYPT PARAMETER LIST 74h/0Dh T ENCRYPTION ALGORITHM DISABLED 74h/10h DZT R MAEBKV SA CREATION PARAMETER VALUE INVALID 74h/11h DZT R MAEBKV SA CREATION PARAMETER VALUE REJECTED 74h/12h DZT R MAEBKV INVALID SA USAGE 74h/21h T DATA ENCRYPTION CONFIGURATION PREVENTED 74h/30h DZT R MAEBKV SA CREATION PARAMETER NOT SUPPORTED 74h/40h DZT R MAEBKV AUTHENTICATION FAILED 74h/61h V EXTERNAL DATA ENCRYPTION KEY MANAGER ACCESS ERROR 74h/62h V EXTERNAL DATA ENCRYPTION KEY MANAGER ERROR 74h/63h V EXTERNAL DATA ENCRYPTION KEY NOT FOUND 74h/64h V EXTERNAL DATA ENCRYPTION REQUEST NOT AUTHORIZED 74h/6Eh T EXTERNAL DATA ENCRYPTION CONTROL TIMEOUT 74h/6Fh T EXTERNAL DATA ENCRYPTION CONTROL ERROR 74h/71h DZT R M E V LOGICAL UNIT ACCESS NOT AUTHORIZED 74h/79h DZ SECURITY CONFLICT IN TRANSLATED DEVICE 75h/00h 76h/00h 77h/00h 78h/00h 79h/00h 7Ah/00h 7Bh/00h 7Ch/00h 7Dh/00h 7Eh/00h 7Fh/00h diskscan-0.21/libscsicmd/structs/ata_identify.yaml000066400000000000000000000121511456470715000224130ustar00rootroot00000000000000ata_identify: not_ata_device: bit: [0, 15] response_incomplete: bit: [0, 2] serial_number: string: [10, 19] fw_rev: string: [23, 26] model: string: [27, 46] # max_num_sectors_transfer_per_drq_multiple: # byte: [40, 1] trusted_computing_supported: bit: [48, 0] standby_timer_values_settable: bit: [49, 13] iordy_supported: bit: [49, 11] iordy_disable_supported: bit: [49, 10] dma_supported: bit: [49, 8] # alignment_error_reporting_field: # bits: [49, 0, 1] # free_fall_sensitivity: # bits: [53, 8, 15] fields_valid_word_88: bit: [53, 2] fields_valid_words_64_70: bit: [53, 1] block_erase_supported: bit: [59, 15] overwrite_supported: bit: [59, 14] crypto_scramble_supported: bit: [59, 13] sanitize_supported: bit: [59, 12] total_addressable_sectors_28bit: longword: 60 cfast_supported: bit: [69, 15] drat_supported: bit: [69, 14] lps_misalignment_reporting_supported: bit: [69, 13] read_buffer_dma_supported: bit: [69, 11] write_buffer_dma_supported: bit: [69, 10] set_max_set_password_dma_and_set_max_unlock_dma_supported: bit: [69, 9] download_microcode_dma_supported: bit: [69, 8] address_28bit_supported: bit: [69, 6] rzat_supported: bit: [69, 5] encrypt_all_supported: bit: [69, 4] extended_number_of_user_addressable_sectors: bit: [69, 3] non_volatile_cache: bit: [69, 2] queue_depth: bits: [75, 0, 4] supports_read_log_dma_ext_as_read_log_dma: bit: [76, 15] supports_dev_automatic_partial_to_slumber: bit: [76, 14] supports_host_automatic_partial_to_slumber: bit: [76, 13] supports_ncq_priority: bit: [76, 12] supports_unload_while_ncq_outstanding: bit: [76, 11] supports_sata_phy_event_counters_log: bit: [76, 10] supports_receipt_of_host_initiated_power_management_requests: bit: [76, 9] supports_ncq: bit: [76, 8] supports_sata_gen3_6gbps: bit: [76, 3] supports_sata_gen2_3gbps: bit: [76, 2] supports_sata_gen1_1_5gbps: bit: [76, 1] supports_receive_fpdma_queued: bit: [77, 6] supports_ncq_queue_management_commands: bit: [77, 5] supports_ncq_streaming: bit: [77, 4] current_negotiated_link_speed: bits: [77, 1, 3] sata_automatic_partial_to_slumber_transitions_enabled: bit: [79, 7] sata_software_settings_preservation_enabled: bit: [79, 6] sata_hardware_feature_control_enabled: bit: [79, 5] sata_in_order_data_delivery_enabled: bit: [79, 4] sata_device_initiated_power_management_enabled: bit: [79, 3] sata_dma_setup_auto_activation_enabled: bit: [79, 2] sata_non_zero_buffer_offsets_enabled: bit: [79, 1] major_version_acs_2: bit: [80, 9] major_version_ata_8_acs: bit: [80, 8] major_version_ata_atapi_7: bit: [80, 7] major_version_ata_atapi_6: bit: [80, 6] major_version_ata_atapi_5: bit: [80, 5] # minor_version: # word: 81 nop_supported: bit: [82, 14] read_buffer_supported: bit: [82, 13] write_buffer_supported: bit: [82, 12] read_look_ahead_supported: bit: [82, 6] volatile_write_cache_supported: bit: [82, 5] packet_feature_set_supported: bit: [82, 4] mandatory_power_management_supported: bit: [82, 3] security_feature_set_supported: bit: [82, 1] smart_supported: bit: [82, 0] address_48bit_supported: bit: [83, 10] spin_up_supported: bit: [83, 6] puis_supported: bit: [83, 5] apm_supported: bit: [83, 3] cfa_supported: bit: [83, 2] download_microcode_supported: bit: [83, 0] wwn_64bit_supported: bit: [84, 8] gpl_supported: bit: [84, 5] streaming_supported: bit: [84, 4] smart_self_test_supported: bit: [84, 1] smart_error_logging_supported: bit: [84, 0] smart_enabled: bit: [85, 0] sense_data_supported: bit: [119, 6] write_uncorrectable_supported: bit: [119, 2] sense_data_enabled: bit: [120, 6] write_uncorrectable_enabled: bit: [120, 2] sct_data_tables_supported: bit: [206, 5] sct_feature_control_supported: bit: [206, 4] sct_error_recovery_control_supported: bit: [206, 3] sct_write_same_supported: bit: [206, 2] sct_command_transport_supported: bit: [206, 0] rotational_rate: bits: [216, 0, 15] wwn_high: longword: 108 wwn_low: longword: 110 additional_product_identifier: string: [170, 173] current_media_serial: string: [176, 205] extended_num_user_addressable_sectors: qword: 230 # vim:set et ts=4 sw=4: diskscan-0.21/libscsicmd/structs/ata_struct_2_c_dump.py000077500000000000000000000044101456470715000233640ustar00rootroot00000000000000#!/usr/bin/env python import sys import yaml def emit_func_bit(name, field, params): bit_params = dict(name=name, field=field, word=int(params[0]), bit=int(params[1])) print('printf("%%-40s: %%s\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf) ? "true" : "false");' % bit_params) def emit_func_string(name, field, params): bit_params = dict(name=name, field=field, word_start=int(params[0]), word_end=int(params[1])) print('{') print('char outbuf[1024];') print('ata_get_%(name)s_%(field)s(buf, outbuf);' % bit_params) print('printf("%%-40s: %%s\\n", "%(field)s", outbuf);' % bit_params) print('}') def emit_func_bits(name, field, params): bit_params = dict(name=name, field=field, word_start=int(params[0])) print('printf("%%-40s: %%u\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) def emit_func_longword(name, field, params): bit_params = dict(name=name, field=field, word_start=int(params)) print('printf("%%-40s: %%u\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) def emit_func_qword(name, field, params): bit_params = dict(name=name, field=field, word_start=int(params)) print('printf("%%-40s: %%"PRIu64"\\n", "%(field)s", ata_get_%(name)s_%(field)s(buf));' % bit_params) kinds = { 'bit': emit_func_bit, 'bits': emit_func_bits, 'string': emit_func_string, 'longword': emit_func_longword, 'qword': emit_func_qword, } def emit_header_single(name, struct): field_names = list(struct.keys()) field_names.sort() for field in field_names: info = struct[field] keys = list(info.keys()) assert(len(keys) == 1) kind = keys[0] params = info[kind] kinds[kind](name, field, params) def emit_header(structs): for name, struct in list(structs.items()): print('void dump_%s(const unsigned char *buf)' % name) print('{') emit_header_single(name, struct) print('}') def emit_prefix(): print('#include "ata.h"') print('#include "ata_parse.h"') print('#include "ata_identify_dump.h"') print('#include ') print('#include ') def emit_suffix(): print('') def convert_def(filename): f = file(filename) structs = yaml.load(f) f.close() emit_header(structs) if __name__ == '__main__': emit_prefix() filenames = sys.argv[1:] for filename in filenames: convert_def(filename) emit_suffix() diskscan-0.21/libscsicmd/structs/ata_struct_2_h.py000077500000000000000000000046731456470715000223570ustar00rootroot00000000000000#!/usr/bin/env python import sys import yaml def emit_func_bit(name, field, params): bit_params = dict(name=name, field=field, word=int(params[0]), bit=int(params[1])) print("""static inline bool ata_get_%(name)s_%(field)s(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, %(word)d); return val & (1 << %(bit)d); } """ % bit_params) def emit_func_bits(name, field, params): bit_params = dict(name=name, field=field, word=int(params[0]), start_bit=int(params[1]), end_bit=int(params[2])) print("""static inline unsigned ata_get_%(name)s_%(field)s(const unsigned char *buf) { ata_word_t val = ata_get_word(buf, %(word)d); return (val >> %(start_bit)d) & ((1<<(%(end_bit)d - %(start_bit)d + 1)) - 1); } """ % bit_params) def emit_func_string(name, field, params): bit_params = dict(name=name, field=field, word_start=int(params[0]), word_end=int(params[1])) print("""static inline void ata_get_%(name)s_%(field)s(const unsigned char *buf, char *out) { ata_get_string(buf, %(word_start)d, %(word_end)d, out); } """ % bit_params) def emit_func_longword(name, field, params): bit_params = dict(name=name, field=field, word_start=int(params)) print("""static inline ata_longword_t ata_get_%(name)s_%(field)s(const unsigned char *buf) { return ata_get_longword(buf, %(word_start)d); } """ % bit_params) def emit_func_qword(name, field, params): bit_params = dict(name=name, field=field, word_start=int(params)) print("""static inline ata_qword_t ata_get_%(name)s_%(field)s(const unsigned char *buf) { return ata_get_qword(buf, %(word_start)d); } """ % bit_params) kinds = { 'bit': emit_func_bit, 'bits': emit_func_bits, 'string': emit_func_string, 'longword': emit_func_longword, 'qword': emit_func_qword, } def emit_header_single(name, struct): for field, info in list(struct.items()): keys = list(info.keys()) assert(len(keys) == 1) kind = keys[0] params = info[kind] kinds[kind](name, field, params) def emit_header(structs): for name, struct in list(structs.items()): emit_header_single(name, struct) def emit_prefix(): print('/* Generated file, do not edit */') print('#ifndef ATA_PARSE_H') print('#define ATA_PARSE_H') print('#include "ata.h"') def emit_suffix(): print('#endif') def convert_def(filename): f = open(filename) structs = yaml.load(f) f.close() emit_header(structs) if __name__ == '__main__': emit_prefix() filenames = sys.argv[1:] for filename in filenames: convert_def(filename) emit_suffix() diskscan-0.21/libscsicmd/structs/ata_struct_2_h_dump.py000077500000000000000000000010171456470715000233710ustar00rootroot00000000000000#!/usr/bin/env python import sys import yaml def emit_header(structs): for name, struct in list(structs.items()): print('void dump_%s(const unsigned char *buf);' % name) def emit_prefix(): print('#ifndef _DUMP_H_') print('#define _DUMP_H_') def emit_suffix(): print('#endif') def convert_def(filename): f = file(filename) structs = yaml.load(f) f.close() emit_header(structs) if __name__ == '__main__': emit_prefix() filenames = sys.argv[1:] for filename in filenames: convert_def(filename) emit_suffix() diskscan-0.21/libscsicmd/structs/update-asc-num000077500000000000000000000004051456470715000216370ustar00rootroot00000000000000#!/bin/sh set -e if [ -d structs ]; then cd structs fi curl 'http://www.t10.org/lists/asc-num.txt' > asc-num.txt.tmp mv asc-num.txt.tmp asc-num.txt dos2unix asc-num.txt ./asc-num-to-list < asc-num.txt > asc-num.h mv asc-num.h ../include/asc_num_list.h diskscan-0.21/libscsicmd/test/000077500000000000000000000000001456470715000163375ustar00rootroot00000000000000diskscan-0.21/libscsicmd/test/CMakeLists.txt000066400000000000000000000037641456470715000211110ustar00rootroot00000000000000add_library(testlib STATIC main.c sense_dump.c) add_executable(ata_check_power_mode ata_check_power_mode.c) target_link_libraries(ata_check_power_mode testlib scsicmd) add_custom_command(OUTPUT ata_identify_dump.h COMMAND ../structs/ata_struct_2_h_dump.py ../structs/ata_identify.yaml > ata_identify_dump.h DEPENDS ../structs/ata_struct_2_h_dump.py ../structs/ata_identify.yaml) add_custom_command(OUTPUT ata_identify_dump.c COMMAND ../structs/ata_struct_2_c_dump.py ../structs/ata_identify.yaml > ata_identify_dump.c DEPENDS ../structs/ata_struct_2_c_dump.py ../structs/ata_identify.yaml) add_executable(ata_identify ata_identify.c ata_identify_dump.c ata_identify_dump.h) target_link_libraries(ata_identify testlib scsicmd) add_executable(ata_smart_read_data ata_smart_read_data.c) target_link_libraries(ata_smart_read_data testlib scsicmd) add_executable(ata_smart_return_status ata_smart_return_status.c) target_link_libraries(ata_smart_return_status testlib scsicmd) add_executable(scsi_inquiry scsi_inquiry.c) target_link_libraries(scsi_inquiry testlib scsicmd) add_executable(scsi_log_sense scsi_log_sense.c) target_link_libraries(scsi_log_sense testlib scsicmd) add_executable(parse_scsi parse_scsi.c) target_link_libraries(parse_scsi testlib scsicmd) add_executable(scsi_mode_sense scsi_mode_sense.c) target_link_libraries(scsi_mode_sense testlib scsicmd) add_executable(scsi_receive_diagnostics scsi_receive_diagnostics.c) target_link_libraries(scsi_receive_diagnostics testlib scsicmd) add_executable(scsi_read_capacity_10 scsi_read_capacity_10.c) target_link_libraries(scsi_read_capacity_10 testlib scsicmd) add_executable(scsi_read_capacity_16 scsi_read_capacity_16.c) target_link_libraries(scsi_read_capacity_16 testlib scsicmd) add_executable(sense_decode sense_decode.c) target_link_libraries(sense_decode testlib scsicmd) add_executable(collect_raw_data collect_raw_data.c) target_link_libraries(collect_raw_data testlib scsicmd) diskscan-0.21/libscsicmd/test/ata_check_power_mode.c000066400000000000000000000027621456470715000226340ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "ata.h" #include "ata_parse.h" #include "main.h" #include #include #include void do_command(int fd) { unsigned char cdb[12]; unsigned char buf[512] ; int cdb_len = cdb_ata_check_power_mode(cdb); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense; unsigned sense_len; ret = read_response(fd, &sense, &sense_len); if (!ret) { fprintf(stderr, "Error reading scsi response\n"); return; } ata_status_t status; if (sense && ata_status_from_scsi_sense(sense, sense_len, &status)) { printf("extend: %d\n", status.extend); printf("error: %02x\n", status.error); printf("lba: %08"PRIx64"\n", status.lba); printf("device: %02x\n", status.device); printf("status: %02x\n", status.status); printf("count: %02x\n", status.sector_count); } } diskscan-0.21/libscsicmd/test/ata_identify.c000066400000000000000000000032051456470715000211430ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "ata.h" #include "ata_parse.h" #include "ata_identify_dump.h" #include "main.h" #include #include #include #include #include #include #include #include #include void do_command(int fd) { unsigned char cdb[32]; unsigned char buf[512] ; unsigned cdb_len = cdb_ata_identify(cdb); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; ret = read_response(fd, &sense, &sense_len); ata_status_t status; if (sense && ata_status_from_scsi_sense(sense, sense_len, &status)) { printf("extend: %d\n", status.extend); printf("error: %02x\n", status.error); printf("lba: %08"PRIx64"\n", status.lba); printf("device: %02x\n", status.device); printf("status: %02x\n", status.status); } if (!sense) dump_ata_identify(buf); else printf("error while reading ATA IDENTIFY, nothing to show\n"); } diskscan-0.21/libscsicmd/test/ata_smart_read_data.c000066400000000000000000000111601456470715000224410ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "ata.h" #include "ata_parse.h" #include "ata_smart.h" #include "sense_dump.h" #include "main.h" #include "smartdb.h" #include #include #include static bool read_data(int fd, unsigned char *buf, int buf_len) { unsigned char cdb[12]; int cdb_len = cdb_ata_smart_read_data(cdb); bool ret = submit_cmd(fd, cdb, cdb_len, buf, buf_len, SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return false; } unsigned char *sense; unsigned sense_len; ret = read_response(fd, &sense, &sense_len); if (!ret) { fprintf(stderr, "Error reading scsi response\n"); return false; } printf("Response Dump:\n"); response_dump(buf, sizeof(buf)); printf("Page checksum read: %02X\n", ata_get_ata_smart_read_data_checksum(buf)); printf("Page checksum calc: %02X\n", ata_calc_checksum(buf)); printf("Page checksum matches: %s\n", ata_check_ata_smart_read_data_checksum(buf) ? "true" : "false"); printf("Page version: %04Xh\n", ata_get_ata_smart_read_data_version(buf)); if (ata_get_ata_smart_read_data_version(buf) != 0x10) { printf("Unknown page version, only known version is 10h\n"); return false; } return true; } static bool read_threshold(int fd, unsigned char *buf, int buf_len) { unsigned char cdb[12]; int cdb_len = cdb_ata_smart_read_threshold(cdb); bool ret = submit_cmd(fd, cdb, cdb_len, buf, buf_len, SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return false; } unsigned char *sense; unsigned sense_len; ret = read_response(fd, &sense, &sense_len); if (!ret) { fprintf(stderr, "Error reading scsi response\n"); return false; } printf("Response Dump:\n"); response_dump(buf, sizeof(buf)); printf("Page checksum read: %02X\n", ata_get_ata_smart_read_data_checksum(buf)); printf("Page checksum calc: %02X\n", ata_calc_checksum(buf)); printf("Page checksum matches: %s\n", ata_check_ata_smart_read_data_checksum(buf) ? "true" : "false"); printf("Page version: %04Xh\n", ata_get_ata_smart_read_data_version(buf)); if (ata_get_ata_smart_read_data_version(buf) != 0x10) { printf("Unknown page version, only known version is 10h\n"); return false; } return true; } void do_command(int fd) { unsigned char buf_thresh[512]; unsigned char buf_data[512]; if (!read_data(fd, buf_data, sizeof(buf_data))) return; if (!read_threshold(fd, buf_thresh, sizeof(buf_thresh))) return; const smart_table_t *table = smart_table_for_disk(NULL, NULL, NULL); ata_smart_attr_t attrs[MAX_SMART_ATTRS]; int num_attrs1 = ata_parse_ata_smart_read_data(buf_data, attrs, MAX_SMART_ATTRS); ata_smart_thresh_t thresholds[MAX_SMART_ATTRS]; int num_attrs2 = ata_parse_ata_smart_read_thresh(buf_thresh, thresholds, MAX_SMART_ATTRS); if (num_attrs1 != num_attrs2) { printf("Number of attributes in data (%d) and thresholds (%d) do not match\n", num_attrs1, num_attrs2); return; } printf("num attributes %d\n", num_attrs1); int i; for (i = 0; i < num_attrs1; i++) { const ata_smart_attr_t *attr = &attrs[i]; const ata_smart_thresh_t *thresh = &thresholds[i]; const smart_attr_t *attr_type = smart_attr_for_id(table, attr->id); printf("Attribute #%2d: id %3u %-40s status %04X val %3u min %3u thresh %3u raw %"PRIu64"\n", i, attr->id, attr_type ? attr_type->name : "Unknown", attr->status, attr->value, attr->min, thresh->threshold, attr->raw); } printf("\nKey attributes:\n"); { int min_temp, max_temp, cur_temp; cur_temp = ata_smart_get_temperature(attrs, num_attrs1, table, &min_temp, &max_temp); printf(" Temperature: %d (min=%d max=%d)\n", cur_temp, min_temp, max_temp); } { int minutes = -1; int hours; hours = ata_smart_get_power_on_hours(attrs, num_attrs1, table, &minutes); printf(" POH: %d (minutes: %d)\n", hours, minutes); } printf(" # Reallocations: %d\n", ata_smart_get_num_reallocations(attrs, num_attrs1, table)); printf(" # Pending Reallocations: %d\n", ata_smart_get_num_pending_reallocations(attrs, num_attrs1, table)); printf(" # CRC Errors: %d\n", ata_smart_get_num_crc_errors(attrs, num_attrs1, table)); } diskscan-0.21/libscsicmd/test/ata_smart_return_status.c000066400000000000000000000032431456470715000234620ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "ata.h" #include "ata_parse.h" #include "main.h" #include #include #include void do_command(int fd) { unsigned char cdb[12]; unsigned char buf[512] ; int cdb_len = cdb_ata_smart_return_status(cdb); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense; unsigned sense_len; ret = read_response(fd, &sense, &sense_len); if (!ret) { fprintf(stderr, "Error reading scsi response\n"); return; } printf("\n"); ata_status_t status; if (ata_status_from_scsi_sense(sense, sense_len, &status)) { printf("extend: %d\n", status.extend); printf("error: %02x\n", status.error); printf("lba: %08" PRIx64 "\n", status.lba); printf("device: %02x\n", status.device); printf("status: %02x\n", status.status); } printf("\n"); bool smart_ok; if (ata_smart_return_status_result(sense, sense_len, &smart_ok)) printf("smart result: %s\n", smart_ok ? "ok" : "failed"); else printf("smart parsing failed\n"); } diskscan-0.21/libscsicmd/test/collect_raw_data.c000066400000000000000000000327261456470715000220040ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include "ata.h" #include "main.h" #include "sense_dump.h" #include "scsicmd_utils.h" #include "parse_extended_inquiry.h" #include "parse_receive_diagnostics.h" #include "parse_log_sense.h" #include #include #include #include #include #include #include #include #include #include static bool is_ata; static void hex_dump(uint8_t *data, uint16_t len) { uint16_t i; if (data == NULL || len == 0) return; printf("%02x", data[0]); for (i = 1; i < len; i++) { printf(" %02x", data[i]); } } static void emit_data_csv(uint8_t *cdb, uint8_t cdb_len, uint8_t *sense, uint8_t sense_len, uint8_t *buf, uint16_t buf_len) { putchar(','); hex_dump(cdb, cdb_len); putchar(','); hex_dump(sense, sense_len); putchar(','); hex_dump(buf, buf_len); putchar('\n'); } static int simple_command(int fd, uint8_t *cdb, unsigned cdb_len, uint8_t *buf, unsigned buf_len) { memset(buf, 0, buf_len); bool ret = submit_cmd(fd, cdb, cdb_len, buf, buf_len, buf_len ? SG_DXFER_FROM_DEV : SG_DXFER_NONE); if (!ret) { printf("Failed to submit command,\n"); return -1; } unsigned char *sense = NULL; unsigned sense_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); emit_data_csv(cdb, cdb_len, sense, sense_len, buf, buf_len); if (sense_len > 0) { sense_info_t sense_info; bool sense_parsed = scsi_parse_sense(sense, sense_len, &sense_info); if (sense_parsed && sense_info.sense_key == SENSE_KEY_RECOVERED_ERROR) return buf_len; return -1; } return buf_len; } static void do_simple_inquiry(int fd) { unsigned char cdb[32]; unsigned char buf[128]; unsigned cdb_len = cdb_inquiry_simple(cdb, 96); int buf_len; buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); int device_type; scsi_vendor_t vendor; scsi_model_t model; scsi_fw_revision_t rev; scsi_serial_t serial; if (parse_inquiry(buf, buf_len, &device_type, vendor, model, rev, serial) && strncmp(vendor, "ATA", 3) == 0) { is_ata = true; } } static void dump_evpd(int fd, uint8_t evpd_page) { unsigned char cdb[32]; unsigned char buf[512]; unsigned cdb_len = cdb_inquiry(cdb, true, evpd_page, sizeof(buf)); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_extended_inquiry(int fd) { unsigned char cdb[32]; unsigned char buf[512]; unsigned cdb_len = cdb_inquiry(cdb, true, 0, sizeof(buf)); int buf_len; buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); if (buf_len > 0 && evpd_is_valid(buf, buf_len)) { uint16_t max_page_idx = evpd_page_len(buf) + 4; uint16_t i; for (i = 4; i < max_page_idx; i++) dump_evpd(fd, buf[i]); } } static void dump_log_sense(int fd, uint8_t page, uint8_t subpage) { unsigned char cdb[32]; unsigned char buf[16*1024]; unsigned cdb_len = cdb_log_sense(cdb, page, subpage, sizeof(buf)); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_log_sense(int fd) { unsigned char cdb[32]; unsigned char buf[16*1024]; unsigned cdb_len = cdb_log_sense(cdb, 0, 0, sizeof(buf)); int buf_len; buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); if (buf_len < 0) { printf("error while reading log sense list, nothing to show\n"); return; } if (!log_sense_is_valid(buf, buf_len)) { printf("log sense page is invalid\n"); return; } if (buf[0] != 0 || buf[1] != 0) { printf("expected to receive log page 0 subpage 0\n"); return; } uint16_t num_pages = get_uint16(buf, 2); uint16_t i; for (i = 0; i < num_pages; i++) { dump_log_sense(fd, buf[4 + i], 0); } cdb_len = cdb_log_sense(cdb, 0, 0xff, sizeof(buf)); buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); if (buf_len < 0) { printf("error while reading list of log subpages, nothing to show\n"); return; } if (!log_sense_is_valid(buf, buf_len)) { printf("log sense list must have at least 4 bytes\n"); return; } if (buf[0] != 0x40 || buf[1] != 0xFF) { printf("expected to receive log page 0 (spf=1) subpage 0xFF\n"); return; } num_pages = get_uint16(buf, 2); for (i = 0; i < num_pages; i++) { uint8_t page = buf[4 + i*2] & 0x3F; uint8_t subpage = buf[4 + i*2 + 1]; if (subpage == 0) { printf("Skipping page %02X subpage %02X since subpage is 00 it was already retrieved above\n", page, subpage); continue; } dump_log_sense(fd, page, subpage); } } static void do_mode_sense_10_type(int fd, bool long_lba, bool disable_block_desc, page_control_e page_control) { unsigned char cdb[32]; unsigned char buf[4096]; unsigned cdb_len = cdb_mode_sense_10(cdb, long_lba, disable_block_desc, page_control, 0x3F, 0xFF, sizeof(buf)); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_mode_sense_10(int fd) { do_mode_sense_10_type(fd, true, true, PAGE_CONTROL_CURRENT); do_mode_sense_10_type(fd, true, true, PAGE_CONTROL_CHANGEABLE); do_mode_sense_10_type(fd, true, true, PAGE_CONTROL_DEFAULT); do_mode_sense_10_type(fd, true, true, PAGE_CONTROL_SAVED); do_mode_sense_10_type(fd, false, true, PAGE_CONTROL_CURRENT); do_mode_sense_10_type(fd, false, true, PAGE_CONTROL_CHANGEABLE); do_mode_sense_10_type(fd, false, true, PAGE_CONTROL_DEFAULT); do_mode_sense_10_type(fd, false, true, PAGE_CONTROL_SAVED); do_mode_sense_10_type(fd, false, false, PAGE_CONTROL_CURRENT); do_mode_sense_10_type(fd, false, false, PAGE_CONTROL_CHANGEABLE); do_mode_sense_10_type(fd, false, false, PAGE_CONTROL_DEFAULT); do_mode_sense_10_type(fd, false, false, PAGE_CONTROL_SAVED); do_mode_sense_10_type(fd, true, false, PAGE_CONTROL_CURRENT); do_mode_sense_10_type(fd, true, false, PAGE_CONTROL_CHANGEABLE); do_mode_sense_10_type(fd, true, false, PAGE_CONTROL_DEFAULT); do_mode_sense_10_type(fd, true, false, PAGE_CONTROL_SAVED); } static void do_mode_sense_6_type(int fd, bool disable_block_desc, page_control_e page_control) { unsigned char cdb[32]; unsigned char buf[255]; unsigned cdb_len = cdb_mode_sense_6(cdb, disable_block_desc, page_control, 0x3F, 0xFF, sizeof(buf)); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_mode_sense_6(int fd) { do_mode_sense_6_type(fd, true, PAGE_CONTROL_CURRENT); do_mode_sense_6_type(fd, true, PAGE_CONTROL_CHANGEABLE); do_mode_sense_6_type(fd, true, PAGE_CONTROL_DEFAULT); do_mode_sense_6_type(fd, true, PAGE_CONTROL_SAVED); do_mode_sense_6_type(fd, false, PAGE_CONTROL_CURRENT); do_mode_sense_6_type(fd, false, PAGE_CONTROL_CHANGEABLE); do_mode_sense_6_type(fd, false, PAGE_CONTROL_DEFAULT); do_mode_sense_6_type(fd, false, PAGE_CONTROL_SAVED); } static void do_mode_sense(int fd) { do_mode_sense_10(fd); do_mode_sense_6(fd); } static void dump_rcv_diag_page(int fd, uint8_t page) { unsigned char cdb[32]; unsigned char buf[16*1024]; unsigned cdb_len = cdb_receive_diagnostics(cdb, true, page, sizeof(buf)); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_receive_diagnostic(int fd) { unsigned char cdb[32]; unsigned char buf[16*1024]; unsigned cdb_len = cdb_receive_diagnostics(cdb, true, 0, sizeof(buf)); int buf_len; buf_len = simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); if (buf_len < 0) { printf("error while reading response buffer, nothing to show\n"); return; } if (recv_diag_is_valid(buf, buf_len)) { printf("receive diagnostics list must have at least 4 bytes\n"); return; } if (recv_diag_get_page_code(buf) != 0) { printf("expected to receive receive diagnostics page 0\n"); return; } uint16_t num_pages = recv_diag_get_len(buf); uint16_t i; for (i = 0; i < num_pages; i++) { dump_rcv_diag_page(fd, buf[4 + i]); } } static void do_read_capacity_10(int fd) { unsigned char cdb[32]; unsigned char buf[8]; unsigned cdb_len = cdb_read_capacity_10(cdb); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_read_capacity_16(int fd) { unsigned char cdb[32]; unsigned char buf[512]; unsigned cdb_len = cdb_read_capacity_16(cdb, sizeof(buf)); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_read_capacity(int fd) { do_read_capacity_10(fd); do_read_capacity_16(fd); } static void do_read_defect_data_10(int fd, bool plist, bool glist, uint8_t format, bool count_only) { unsigned char cdb[32]; unsigned char buf[512]; unsigned cdb_len = cdb_read_defect_data_10(cdb, plist, glist, format, count_only ? 8 : sizeof(buf)); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_read_defect_data_10_all(int fd, uint8_t format) { do_read_defect_data_10(fd, true, false, format, true); do_read_defect_data_10(fd, true, false, format, false); do_read_defect_data_10(fd, false, true, format, true); do_read_defect_data_10(fd, false, true, format, false); } static void do_read_defect_data_12(int fd, bool plist, bool glist, uint8_t format, bool count_only) { unsigned char cdb[32]; unsigned char buf[512]; unsigned cdb_len = cdb_read_defect_data_12(cdb, plist, glist, format, count_only ? 8 : sizeof(buf)); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_read_defect_data_12_all(int fd, uint8_t format) { do_read_defect_data_12(fd, true, false, format, true); do_read_defect_data_12(fd, true, false, format, false); do_read_defect_data_12(fd, false, true, format, true); do_read_defect_data_12(fd, false, true, format, false); } static void do_read_defect_data(int fd) { uint8_t format; for (format = 0; format < 8; format++) do_read_defect_data_10_all(fd, format); for (format = 0; format < 8; format++) do_read_defect_data_12_all(fd, format); } static void do_ata_identify(int fd) { uint8_t cdb[32]; int cdb_len; uint8_t buf[512]; cdb_len = cdb_ata_identify(cdb); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_ata_identify_16(int fd) { uint8_t cdb[32]; int cdb_len; uint8_t buf[512]; cdb_len = cdb_ata_identify_16(cdb); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_ata_smart_return_status(int fd) { uint8_t cdb[32]; int cdb_len; uint8_t buf[512]; cdb_len = cdb_ata_smart_return_status(cdb); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_ata_smart_read_data(int fd) { uint8_t cdb[32]; int cdb_len; uint8_t buf[512]; cdb_len = cdb_ata_smart_read_data(cdb); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static void do_ata_smart_read_threshold(int fd) { uint8_t cdb[32]; int cdb_len; uint8_t buf[512]; cdb_len = cdb_ata_smart_read_threshold(cdb); simple_command(fd, cdb, cdb_len, buf, sizeof(buf)); } static int do_ata_read_log_ext_page(int fd, uint8_t *buf, unsigned buf_sz, unsigned log_addr, unsigned page) { uint8_t cdb[32]; int cdb_len; cdb_len = cdb_ata_read_log_ext(cdb, 1, page, log_addr); return simple_command(fd, cdb, cdb_len, buf, buf_sz); } static void do_ata_read_log_ext(int fd) { uint8_t __attribute__((aligned(512))) buf[512]; uint8_t __attribute__((aligned(512))) buf_data[512]; unsigned log_addr; do_ata_read_log_ext_page(fd, buf, sizeof(buf), 0, 0); // Validate the page is valid if (buf[0] != 1 || buf[1] != 0) return; for (log_addr = 1; log_addr < sizeof(buf)/2; log_addr++) { unsigned num_pages = ata_get_word(buf, log_addr); if (num_pages) { unsigned page; for (page = 0; page < num_pages; page++) { printf("READ LOG EXT log addr %02X page %u/%u\n", log_addr, page, num_pages); int ret = do_ata_read_log_ext_page(fd, buf_data, sizeof(buf_data), log_addr, page); if (ret < 0) break; } } } } static int do_ata_smart_read_log_addr(int fd, unsigned char *buf, unsigned buf_sz, uint8_t log_addr, uint8_t block_count) { uint8_t cdb[32]; int cdb_len; cdb_len = cdb_ata_smart_read_log(cdb, log_addr, block_count); return simple_command(fd, cdb, cdb_len, buf, buf_sz); } static void do_ata_smart_read_log(int fd) { unsigned log_addr; uint8_t __attribute__((aligned(512))) buf[512]; uint8_t __attribute__((aligned(512))) buf_data[512*256]; int ret = do_ata_smart_read_log_addr(fd, buf, sizeof(buf), 0, 1); if (ret < (int)sizeof(buf)) return; // Validate the page is valid if (buf[0] != 1 || buf[1] != 0) return; for (log_addr = 1; log_addr < 255; log_addr++) { unsigned num_pages = buf[log_addr*2]; if (num_pages > 0) { printf("SMART READ LOG log addr %02X pages %u\n", log_addr, num_pages); fflush(stdout); do_ata_smart_read_log_addr(fd, buf_data, 512*num_pages, log_addr, num_pages); } } } static void do_ata_check_power_mode(int fd) { uint8_t cdb[32]; int cdb_len; printf("Check power mode\n"); cdb_len = cdb_ata_check_power_mode(cdb); simple_command(fd, cdb, cdb_len, NULL, 0); } void do_command(int fd) { debug = 0; is_ata = false; printf("msg,cdb,sense,data\n"); do_read_capacity(fd); do_simple_inquiry(fd); do_extended_inquiry(fd); do_log_sense(fd); do_mode_sense(fd); do_receive_diagnostic(fd); do_read_defect_data(fd); if (is_ata) { do_ata_identify(fd); do_ata_identify_16(fd); do_ata_check_power_mode(fd); do_ata_smart_return_status(fd); do_ata_smart_read_data(fd); do_ata_smart_read_threshold(fd); do_ata_read_log_ext(fd); do_ata_smart_read_log(fd); } } diskscan-0.21/libscsicmd/test/main.c000066400000000000000000000053201456470715000174270ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "ata.h" #include "ata_parse.h" #include "main.h" #include "sense_dump.h" #include #include #include #include #include #include #include #include static unsigned char sense[128]; int debug = 1; bool submit_cmd(int fd, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_len, int dxfer_dir) { sg_io_hdr_t hdr; if (debug) cdb_dump(cdb, cdb_len); memset(&hdr, 0, sizeof(hdr)); hdr.interface_id = 'S'; hdr.dxfer_direction = dxfer_dir; hdr.cmd_len = cdb_len; hdr.mx_sb_len = sizeof(sense); hdr.dxfer_len = buf_len; hdr.dxferp = buf; hdr.cmdp = cdb; hdr.sbp = sense; hdr.timeout = 30*1000; hdr.flags = SG_FLAG_LUN_INHIBIT; hdr.pack_id = 0; hdr.usr_ptr = 0; ssize_t ret = write(fd, &hdr, sizeof(hdr)); return ret == sizeof(hdr); } bool read_response_buf(int fd, unsigned char **sensep, unsigned *sense_len, unsigned *buf_read) { *sensep = NULL; *sense_len = 0; sg_io_hdr_t hdr; int ret = read(fd, &hdr, sizeof(hdr)); if (ret != sizeof(hdr)) { fprintf(stderr, "Error reading scsi response, ret=%d, expected=%d, %m\n", ret, (int)sizeof(hdr)); return false; } printf("status: %d\n", hdr.status); printf("masked status: %d\n", hdr.masked_status); printf("driver status: %d\n", hdr.driver_status); printf("msg status: %d\n", hdr.msg_status); printf("host status: %d\n", hdr.host_status); printf("sense len: %d\n", hdr.sb_len_wr); if (hdr.sb_len_wr) { *sensep = sense; *sense_len = hdr.sb_len_wr; if (debug) { printf("sense data:\n"); sense_dump(sense, hdr.sb_len_wr); } } if (buf_read) *buf_read = hdr.dxfer_len - hdr.resid; return true; } static void test(const char *devname) { int fd = open(devname, O_RDWR); if (fd < 0) { fprintf(stderr, "Error opening device '%s': %m\n", devname); return; } do_command(fd); close(fd); } static int usage(char *name) { fprintf(stderr, "Usage:\n"); fprintf(stderr, "\t%s disk_device\n", name); return 1; } int main(int argc, char **argv) { if (argc != 2 || strstr(argv[1], "/sd") != NULL) return usage(argv[0]); test(argv[1]); return 0; } diskscan-0.21/libscsicmd/test/main.h000066400000000000000000000010511456470715000174310ustar00rootroot00000000000000#ifndef LIBSCSICMD_TEST_H #define LIBSCSICMD_TEST_H #include extern int debug; /** Do the command that we want to test on the open disk interface. */ void do_command(int fd); bool submit_cmd(int fd, unsigned char *cdb, unsigned cdb_len, unsigned char *buf, unsigned buf_len, int dxfer_dir); bool read_response_buf(int fd, unsigned char **sense, unsigned *sense_len, unsigned *buf_read); static inline bool read_response(int fd, unsigned char **sense, unsigned *sense_len) { return read_response_buf(fd, sense, sense_len, NULL); } #endif diskscan-0.21/libscsicmd/test/parse_scsi.c000066400000000000000000000541501456470715000206430ustar00rootroot00000000000000#include #include #include #include #include #include #include "parse_log_sense.h" #include "parse_mode_sense.h" #include "parse_extended_inquiry.h" #include "parse_read_defect_data.h" #include "parse_receive_diagnostics.h" #include "scsicmd.h" #include "sense_dump.h" #ifndef __AFL_LOOP #define __AFL_LOOP(count) 1 #endif static char *csvtok_last; static void csvtok_reset(void) { csvtok_last = NULL; } static char *csvtok(char *start) { if (start) csvtok_last = start; if (!csvtok_last) return NULL; char *ret = csvtok_last; for (; *csvtok_last && *csvtok_last != ','; csvtok_last++) ; if (*csvtok_last) { *csvtok_last = 0; csvtok_last++; } else csvtok_last = NULL; return ret; } static unsigned char char2val(unsigned char 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 0; } static void print_hex(uint8_t *buf, unsigned buf_len) { unsigned i; for (i = 0; i < buf_len; i++) { printf("%02x ", buf[i]); } printf("\n"); } static unsigned char *parse_hex(char *str, int *len_out) { char buf[64*1024]; const unsigned buf_size = sizeof(buf); unsigned char ch; unsigned len = 0; bool top_char = true; *len_out = -1; for (; *str && len < buf_size; str++) { if (isspace(*str)) { if (!top_char) { printf("Leftover character\n"); return NULL; } } else if (isxdigit(*str)) { if (top_char) { ch = char2val(*str); top_char = false; } else { buf[len++] = (ch<<4) | char2val(*str); top_char = true; } } else { printf("Unknown character '%c'\n", *str); return NULL; } } // For valgrind and AFL, copy the data to a malloc buffer to easily detect out of bounds accesses unsigned char *out = malloc(len); memcpy(out, buf, len); *len_out = len; return out; } static inline const char *yes_no(bool val) { return val ? "yes" : "no"; } static void unparsed_data(uint8_t *buf, unsigned buf_len, uint8_t *start, unsigned total_len) { const unsigned len = safe_len(start, total_len, buf, buf_len); printf("Unparsed data: "); print_hex(buf, len); } static void parse_log_sense_param_informational_exceptions(uint16_t param_code, uint8_t *param, uint8_t param_len) { switch (param_code) { case 0: printf("Information Exceptions ASC: %02X\n", param[0]); printf("Information Exceptions ASCQ: %02X\n", param[1]); printf("Temperature: %u\n", param[2]); if (param_len > 3) unparsed_data(param+3, param_len-3, param, param_len); break; default: unparsed_data(param, param_len, param, param_len); } } static void parse_log_sense_param_ascii(uint8_t *param, unsigned param_len) { uint8_t *ascii = log_sense_param_data(param); unsigned ascii_len = log_sense_param_len(param); ascii_len = safe_len(param, param_len, ascii, ascii_len); printf("ASCII (%u): '", ascii_len); for (; ascii_len > 0; ascii_len--, ascii++) putchar(*ascii); printf("'\n"); } static void parse_log_sense_param_counter(uint8_t *param, unsigned param_len) { uint8_t *data = log_sense_param_data(param); unsigned data_len = log_sense_param_len(param); switch (data_len) { case 2: printf("Counter 16bit: %u\n", get_uint16(data, 0)); break; case 4: printf("Counter 32bit: %u\n", get_uint32(data, 0)); break; case 8: printf("Counter 64bit: %lu\n", get_uint64(data, 0)); break; default: printf("Counter %d bytes\n", data_len); unparsed_data(data, data_len, param, param_len); break; } } static void parse_log_sense_param(uint8_t page, uint8_t subpage, uint16_t param_code, uint8_t *param, uint8_t param_len) { (void)subpage; switch (page) { case 0x2F: parse_log_sense_param_informational_exceptions(param_code, log_sense_param_data(param), log_sense_param_len(param)); break; /* TODO: parse more LOG SENSE pages */ default: switch (log_sense_param_fmt(param)) { case LOG_PARAM_FMT_COUNTER_STOP: case LOG_PARAM_FMT_COUNTER_ROLLOVER: parse_log_sense_param_counter(param, param_len); break; case LOG_PARAM_FMT_ASCII: parse_log_sense_param_ascii(param, param_len); break; default: unparsed_data(param, param_len, param, param_len); break; } break; } } static int parse_log_sense(unsigned char *data, unsigned data_len) { printf("Log Sense\n"); if (data_len < LOG_SENSE_MIN_LEN) { printf("Insufficient data in log sense to begin parsing\n"); return 1; } printf("Log Sense Page Code: 0x%02x\n", log_sense_page_code(data)); printf("Log Sense Subpage format: %s\n", yes_no(log_sense_subpage_format(data))); if (log_sense_subpage_format(data)) printf("Log Sense Subpage: 0x%02x\n", log_sense_subpage_code(data)); printf("Log Sense Data Saved: %s\n", yes_no(log_sense_data_saved(data))); printf("Log Sense Data Length: %u\n", log_sense_data_len(data)); if (log_sense_page_code(data) == 0) { if (!log_sense_subpage_format(data)) { printf("Supported Log Pages:\n"); uint8_t supported_page; for_all_log_sense_pg_0_supported_pages(data, data_len, supported_page) { printf("\t%02X\n", supported_page & 0x3F); } } else if (log_sense_subpage_code(data) == 0xFF) { printf("Supported Log Subpages:\n"); uint8_t supported_page, supported_subpage; for_all_log_sense_pg_0_supported_subpages(data, data_len, supported_page, supported_subpage) { printf("\t%02X %02X\n", supported_page & 0x3F, supported_subpage); } } else { printf("Unknown supported log page combination"); unparsed_data(log_sense_data(data), log_sense_data_len(data), data, data_len); } } else { uint8_t *param; for_all_log_sense_params(data, data_len, param) { putchar('\n'); printf("Log Sense Param Code: 0x%04x\n", log_sense_param_code(param)); printf("Log Sense Param Len: %u\n", log_sense_param_len(param)); printf("Log Sense Param format: %u\n", log_sense_param_fmt(param)); parse_log_sense_param(log_sense_page_code(data), log_sense_subpage_code(data), log_sense_param_code(param), param, log_sense_param_len(param) + 4); } } return 0; } static int parse_read_cap_10(unsigned char *data, unsigned data_len) { uint32_t max_lba; uint32_t block_size; bool parsed = parse_read_capacity_10(data, data_len, &max_lba, &block_size); printf("Read Capacity 10\n"); if (!parsed) { unparsed_data(data, data_len, data, data_len); return 1; } printf("Max LBA: %u\n", max_lba); printf("Block Size: %u\n", block_size); if (data_len > 8) unparsed_data(data+8, data_len-8, data, data_len); return 0; } static int parse_read_cap_16(unsigned char *data, unsigned data_len) { uint64_t max_lba; uint32_t block_size; bool prot_enable, thin_provisioning_enabled, thin_provisioning_zero; unsigned p_type, p_i_exponent, logical_blocks_per_physical_block_exponent, lowest_aligned_lba; printf("Read Capacity 16\n"); bool parsed = parse_read_capacity_16(data, data_len, &max_lba, &block_size, &prot_enable, &p_type, &p_i_exponent, &logical_blocks_per_physical_block_exponent, &thin_provisioning_enabled, &thin_provisioning_zero, &lowest_aligned_lba); if (!parsed) { unparsed_data(data, data_len, data, data_len); return 1; } printf("Max LBA: %lu\n", max_lba); printf("Block Size: %u\n", block_size); printf("Protection enabled: %s\n", yes_no(prot_enable)); printf("Thin Provisioning enabled: %s\n", yes_no(thin_provisioning_enabled)); printf("Thin Provisioning zero: %s\n", yes_no(thin_provisioning_zero)); printf("P Type: %u\n", p_type); printf("Pi Exponent: %u\n", p_i_exponent); printf("Logical blocks per physical block exponent: %u\n", logical_blocks_per_physical_block_exponent); printf("Lowest aligned LBA: %u\n", lowest_aligned_lba); return 0; } static int parse_extended_inquiry_data(uint8_t *data, unsigned data_len) { printf("Extended Inquiry\n"); if (data_len < EVPD_MIN_LEN) { printf("Not enough data for EVPD header\n"); unparsed_data(data, data_len, data, data_len); return 1; } printf("Peripheral Qualifier: %d\n", evpd_peripheral_qualifier(data)); printf("Peripheral Device Type: %d\n", evpd_peripheral_device_type(data)); printf("EVPD page code: 0x%02X\n", evpd_page_code(data)); printf("EVPD data len: %u\n", evpd_page_len(data)); if (!evpd_is_valid(data, data_len)) return 0; uint8_t *page_data = evpd_page_data(data); if (evpd_is_ascii_page(evpd_page_code(data))) { printf("ASCII len: %u\n", evpd_ascii_len(page_data)); printf("ASCII string: '%*s'\n", evpd_ascii_len(page_data), evpd_ascii_data(page_data)); if (evpd_ascii_post_data_len(page_data, data_len) > 0) unparsed_data(evpd_ascii_post_data(page_data), evpd_ascii_post_data_len(page_data, data_len), data, data_len); } else { /* TODO: parse more of the extended inquiry pages */ unparsed_data(page_data, evpd_page_len(data), data, data_len); } return 0; } static int parse_simple_inquiry_data(uint8_t *data, unsigned data_len) { int device_type; scsi_vendor_t vendor; scsi_model_t model; scsi_fw_revision_t rev; scsi_serial_t serial; bool parsed = parse_inquiry(data, data_len, &device_type, vendor, model, rev, serial); printf("Simple Inquiry\n"); if (!parsed) { unparsed_data(data, data_len, data, data_len); return 1; } printf("Device Type: %d\n", device_type); printf("Vendor: %s\n", vendor); printf("Model: %s\n", model); printf("FW Revision: %s\n", rev); printf("Serial: %s\n", serial); return 0; } static int parse_inquiry_data(uint8_t *cdb, unsigned cdb_len, uint8_t *data, unsigned data_len) { if (cdb_len < 6) return 1; if (cdb[1] & 1) return parse_extended_inquiry_data(data, data_len); else return parse_simple_inquiry_data(data, data_len); } static void parse_mode_sense_block_descriptor(uint8_t *data, unsigned data_len) { if (data_len != BLOCK_DESCRIPTOR_LENGTH) { printf("Unknown block descriptor\n"); unparsed_data(data, data_len, data, data_len); return; } printf("Density code: %u\n", block_descriptor_density_code(data)); printf("Num blocks: %u\n", block_descriptor_num_blocks(data)); printf("Block length: %u\n", block_descriptor_block_length(data)); } static void parse_mode_sense_data_page(uint8_t *data, unsigned data_len) { bool subpage_format = mode_sense_data_subpage_format(data); printf("\nPage code: 0x%02x\n", mode_sense_data_page_code(data)); if (subpage_format) printf("Subpage code: 0x%02x\n", mode_sense_data_subpage_code(data)); printf("Page Saveable: %s\n", yes_no(mode_sense_data_parameter_saveable(data))); printf("Page len: %u\n", mode_sense_data_param_len(data)); /* TODO: Parse the mode sense data */ unparsed_data(mode_sense_data_param(data), mode_sense_data_param_len(data), data, data_len); } static int parse_mode_sense_10(uint8_t *data, unsigned data_len) { printf("Mode Sense 10\n"); if (data_len < MODE_SENSE_10_MIN_LEN) { printf("Not enough data for MODE SENSE header\n"); unparsed_data(data, data_len, data, data_len); return 1; } printf("Mode Sense 10 data length: %u\n", mode_sense_10_data_len(data)); printf("Mode Sense 10 medium type: %u\n", mode_sense_10_medium_type(data)); printf("Mode Sense 10 Device specific param: %u\n", mode_sense_10_device_specific_param(data)); printf("Mode Sense 10 Long LBA: %s\n", yes_no(mode_sense_10_long_lba(data))); printf("Mode Sense 10 Block descriptor length: %u\n", mode_sense_10_block_descriptor_length(data)); if (data_len < mode_sense_10_expected_length(data)) { printf("Not enough data to parse full data\n"); unparsed_data(data + MODE_SENSE_10_MIN_LEN, data_len - MODE_SENSE_10_MIN_LEN, data, data_len); return 1; } if (mode_sense_10_block_descriptor_length(data) > 0) { const unsigned safe_desc_len = safe_len(data, data_len, mode_sense_10_block_descriptor_data(data), mode_sense_10_block_descriptor_length(data)); parse_mode_sense_block_descriptor(mode_sense_10_block_descriptor_data(data), safe_desc_len); } unsigned remaining_len; uint8_t *mode_page; for_all_mode_sense_10_pages(data, data_len, mode_page, remaining_len) { printf("\nRemaining len: %u\n", remaining_len); parse_mode_sense_data_page(mode_page, remaining_len); } return 0; } static int parse_mode_sense_6(uint8_t *data, unsigned data_len) { printf("Mode Sense 6\n"); if (data_len < MODE_SENSE_6_MIN_LEN) { printf("Not enough data for MODE SENSE 6 header\n"); unparsed_data(data, data_len, data, data_len); return 1; } printf("Mode Sense 6 data length: %u\n", mode_sense_6_data_len(data)); printf("Mode Sense 6 medium type: %u\n", mode_sense_6_medium_type(data)); printf("Mode Sense 6 Device specific param: %u\n", mode_sense_6_device_specific_param(data)); printf("Mode Sense 6 Block descriptor length: %u\n", mode_sense_6_block_descriptor_length(data)); if (data_len < mode_sense_6_expected_length(data)) { printf("Not enough data to parse full data\n"); unparsed_data(data + MODE_SENSE_6_MIN_LEN, data_len - MODE_SENSE_6_MIN_LEN, data, data_len); return 1; } if (!mode_sense_6_is_valid_header(data, data_len)) { printf("Bad data in mode sense header\n"); return 1; } if (mode_sense_6_block_descriptor_length(data) > 0) { unsigned safe_desc_len = safe_len(data, data_len, mode_sense_6_block_descriptor_data(data), mode_sense_6_block_descriptor_length(data)); parse_mode_sense_block_descriptor(mode_sense_6_block_descriptor_data(data), safe_desc_len); } unsigned remaining_len; uint8_t *mode_page; for_all_mode_sense_6_pages(data, data_len, mode_page, remaining_len) { printf("Remaining len: %u\n", remaining_len); parse_mode_sense_data_page(mode_page, remaining_len); } return 0; } static void read_defect_data_format(address_desc_format_e fmt, uint8_t *data, unsigned len) { const unsigned fmt_len = read_defect_data_fmt_len(fmt); if (fmt_len == 0) { printf("Unknown format to decode\n"); unparsed_data(data, len, data, len); return; } for (; len > fmt_len; data += fmt_len, len -= fmt_len) { switch (fmt) { case ADDRESS_FORMAT_SHORT: printf("\t%u\n", get_uint32(data, 0)); break; case ADDRESS_FORMAT_LONG: printf("\t%lu\n", get_uint64(data, 0)); break; case ADDRESS_FORMAT_INDEX_OFFSET: printf("\tC=%u H=%u B=%u\n", format_address_byte_from_index_cylinder(data), format_address_byte_from_index_head(data), format_address_byte_from_index_bytes(data)); break; case ADDRESS_FORMAT_PHYSICAL: printf("\tC=%u H=%u S=%u\n", format_address_physical_cylinder(data), format_address_physical_head(data), format_address_physical_sector(data)); break; case ADDRESS_FORMAT_VENDOR: printf("\t%08x\n", get_uint32(data, 0)); break; default: break; } } } static int parse_read_defect_data_10(uint8_t *data, unsigned data_len) { printf("Read Defect Data 10\n"); if (!read_defect_data_10_hdr_is_valid(data, data_len)) { printf("Header is not valid\n"); unparsed_data(data, data_len, data, data_len); return 1; } printf("Plist: %s\n", yes_no(read_defect_data_10_is_plist_valid(data))); printf("Glist: %s\n", yes_no(read_defect_data_10_is_glist_valid(data))); printf("Format: %s\n", read_defect_data_format_to_str(read_defect_data_10_list_format(data))); printf("Len: %u\n", read_defect_data_10_len(data)); if (!read_defect_data_10_is_valid(data, data_len)) return 0; if (data_len > 0) { const unsigned len = safe_len(data, data_len, read_defect_data_10_data(data), read_defect_data_10_len(data)); read_defect_data_format(read_defect_data_10_list_format(data), read_defect_data_10_data(data), len); } return 0; } static int parse_read_defect_data_12(uint8_t *data, unsigned data_len) { printf("Read Defect Data 12\n"); if (!read_defect_data_12_hdr_is_valid(data, data_len)) { printf("Header is not valid\n"); unparsed_data(data, data_len, data, data_len); return 1; } printf("Plist: %s\n", yes_no(read_defect_data_12_is_plist_valid(data))); printf("Glist: %s\n", yes_no(read_defect_data_12_is_glist_valid(data))); printf("Format: %s\n", read_defect_data_format_to_str(read_defect_data_12_list_format(data))); printf("Len: %u\n", read_defect_data_12_len(data)); if (!read_defect_data_12_is_valid(data, data_len)) return 0; if (data_len > 0) { const unsigned len = safe_len(data, data_len, read_defect_data_10_data(data), read_defect_data_10_len(data)); read_defect_data_format(read_defect_data_12_list_format(data), read_defect_data_12_data(data), len); } return 0; } static void parse_receive_diagnostic_results_pg_0(uint8_t *data, unsigned data_len) { printf("Supported Receive Diagnostic Results pages:\n"); for (; data_len > 0; data_len--, data++) printf("\t0x%02x\n", data[0]); } static unsigned parse_enclosure_descriptor(uint8_t *data, unsigned data_len) { char name[16]; if (!ses_config_enclosure_descriptor_is_valid(data, data_len)) return data_len; printf("\nProcess identifier: %u\n", ses_config_enclosure_descriptor_process_identifier(data)); printf("Num processes: %u\n", ses_config_enclosure_descriptor_num_processes(data)); printf("Subenclosure identifier: %u\n", ses_config_enclosure_descriptor_subenclosure_identifier(data)); printf("Num Type Descriptors: %u\n", ses_config_enclosure_descriptor_num_type_descriptors(data)); printf("Enclosure descriptor len: %u\n", ses_config_enclosure_descriptor_len(data)); printf("Logical identified: %016lx\n", ses_config_enclosure_descriptor_logical_identifier(data)); ses_config_enclosure_descriptor_vendor_identifier(data, name, sizeof(name)); printf("Vendor identifier: %s\n", name); ses_config_enclosure_descriptor_product_identifier(data, name, sizeof(name)); printf("Product identifier: %s\n", name); ses_config_enclosure_descriptor_revision_level(data, name, sizeof(name)); printf("Revision level: %s\n", name); printf("Vendor info len: %u\n", ses_config_enclosure_descriptor_vendor_len(data)); if (ses_config_enclosure_descriptor_vendor_len(data) > 0) unparsed_data(ses_config_enclosure_descriptor_vendor_info(data), ses_config_enclosure_descriptor_vendor_len(data), data, data_len); return ses_config_enclosure_descriptor_len(data) + 4; } static void parse_receive_diagnostic_results_pg_1(uint8_t *data, unsigned data_len) { unsigned parsed_len = 8; unsigned num_enclosures; if (!ses_config_is_valid(data, data_len)) return; printf("SES config page:\n"); num_enclosures = ses_config_num_sub_enclosures(data); printf("Num subenclosures: %u\n", num_enclosures); printf("Generation code: %u\n", ses_config_generation(data)); for (; num_enclosures > 0 && parsed_len < data_len; num_enclosures--) parsed_len += parse_enclosure_descriptor(ses_config_sub_enclosure(data), data_len-parsed_len); /* TODO: There can be additional enclosures and type descriptors and strings */ unparsed_data(data + parsed_len, data_len - parsed_len, data, data_len); } static int parse_receive_diagnostic_results(uint8_t *data, unsigned data_len) { printf("Receive Diagnostic Results\n"); if (!recv_diag_is_valid(data, data_len)) { printf("Data is not valid\n"); return 1; } printf("Page code: 0x%02X\n", recv_diag_get_page_code(data)); printf("Page code specific: 0x%02x\n", recv_diag_get_page_code_specific(data)); printf("Len: %u\n", recv_diag_get_len(data)); switch (recv_diag_get_page_code(data)) { case 0: parse_receive_diagnostic_results_pg_0(recv_diag_data(data), safe_len(data, data_len, recv_diag_data(data), recv_diag_get_len(data))); break; case 1: parse_receive_diagnostic_results_pg_1(data, data_len); break; default: unparsed_data(recv_diag_data(data), recv_diag_get_len(data), data, data_len); /* TODO: parse SES pages */ break; } return 0; } static void process_data(char *cdb_src, char *sense_src, char *data_src) { unsigned char *cdb = NULL; unsigned char *sense = NULL; unsigned char *data = NULL; int cdb_len, sense_len, data_len; printf("CDB: %s\n", cdb_src); printf("Sense: %s\n", sense_src); printf("Data: %s\n", data_src); if (cdb_src == NULL || sense_src == NULL || data_src == NULL) { printf("Input csv is invalid\n"); return; } cdb = parse_hex(cdb_src, &cdb_len); sense = parse_hex(sense_src, &sense_len); data = parse_hex(data_src, &data_len); printf("CDB Len: %d\n", cdb_len); printf("Sense Len: %d\n", sense_len); printf("Data Len: %d\n", data_len); if (cdb_len < 0) { printf("Failed to parse CDB\n"); goto Exit; } if (sense_len < 0) { printf("Failed to parse SENSE\n"); goto Exit; } if (data_len < 0) { printf("Failed to parse DATA\n"); goto Exit; } if (sense_len > 0) { printf("Sense data indicates an error, not parsing data\n"); sense_dump(sense, sense_len); goto Exit; } switch (cdb[0]) { case 0x4D: parse_log_sense(data, data_len); break; case 0x25: parse_read_cap_10(data, data_len); break; case 0x9E: parse_read_cap_16(data, data_len); break; case 0x12: parse_inquiry_data(cdb, cdb_len, data, data_len); break; case 0x5A: parse_mode_sense_10(data, data_len); break; case 0x1A: parse_mode_sense_6(data, data_len); break; case 0x1C: parse_receive_diagnostic_results(data, data_len); break; case 0x37: parse_read_defect_data_10(data, data_len); break; case 0xB7: parse_read_defect_data_12(data, data_len); break; default: printf("Unsupported CDB opcode %02X\n", cdb[0]); unparsed_data(data, data_len, data, data_len); break; } Exit: free(cdb); free(sense); free(data); } static ssize_t read_newline(char *buf, size_t buf_sz) { ssize_t data_read = 0; while (data_read < (ssize_t)buf_sz) { int ch = getchar(); if (ch == EOF) break; if (ch == '\n' || ch == '\r') return data_read; buf[data_read++] = ch; } return data_read; } int main(int argc, char **argv) { char *cdb_src, *sense_src, *data_src; if (argc != 4 && argc != 1) { printf("Usage: %s \"cdb\" \"sense\" \"data\"\n", argv[0]); return 1; } if (argc == 1) { while (__AFL_LOOP(30000)) { char buf[64*1024]; memset(buf, 0, sizeof(buf)); int ret = read_newline(buf, sizeof(buf)); if (ret <= 0) { printf("Insufficient input\n"); return 1; } buf[ret] = 0; csvtok_reset(); csvtok(buf); cdb_src = csvtok(NULL); sense_src = csvtok(NULL); data_src = csvtok(NULL); process_data(cdb_src, sense_src, data_src); printf("=================================================================================\n"); } } else { cdb_src = argv[1]; sense_src = argv[2]; data_src = argv[3]; process_data(cdb_src, sense_src, data_src); } return 0; } diskscan-0.21/libscsicmd/test/samples/000077500000000000000000000000001456470715000200035ustar00rootroot00000000000000diskscan-0.21/libscsicmd/test/samples/breakout.py000077500000000000000000000016401456470715000221750ustar00rootroot00000000000000#!/usr/bin/env python import sys import subprocess files = { ',4d ' : 'log_sense', ',25 ' : 'read_cap_10', ',9e ' : 'read_cap_16', ',12 ' : 'inquiry', ',5a ' : 'mode_sense_10', ',1a ' : 'mode_sense_6', ',37 ' : 'read_defect_data_10', ',b7 ' : 'read_defect_data_12', ',1c ' : 'receive_diagnostics', } for key in files.keys(): filename = files[key] + '.csv.bz2' f = subprocess.Popen(['/bin/bzip2', '-z', '-c', '-9'], stdin=subprocess.PIPE, stdout=file(filename, 'w')) if f is None: print 'Failed to create process for', filename files[key] = f for line in sys.stdin: prefix = line[0:4] f = files.get(prefix, None) if f is None: print '"%s"' % prefix continue f.stdin.write(line) for key in files.keys(): print 'Closing', key files[key].stdin.close() files[key].wait() print 'Done' diskscan-0.21/libscsicmd/test/samples/parse_file.py000077500000000000000000000016021456470715000224700ustar00rootroot00000000000000#!/usr/bin/env python import sys import csv import os def parse_file(f): c = csv.reader(f) for line in c: msg = line[0] if msg != '': continue if len(line) != 4: continue cdb = line[1] sense = line[2] data = line[3] print('Parsing CDB: %s' % cdb) print('Parsing Sense: %s' % sense) print('Parsing Data: %s' % data) sys.stdout.flush() sys.stderr.flush() os.system('../parse_scsi "%s" "%s" "%s"' % (cdb, sense, data)) sys.stdout.flush() sys.stderr.flush() print('=========================================================================\n') if len(sys.argv) > 1: for filename in sys.argv[1:]: print('Parsing file %s' % filename) f = file(filename, 'r') parse_file(f) print('Done') print('') else: parse_file(sys.stdin) diskscan-0.21/libscsicmd/test/scsi_inquiry.c000066400000000000000000000110601456470715000212220ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include "main.h" #include "sense_dump.h" #include "parse_extended_inquiry.h" #include #include #include #include #include #include #include #include #include #include static void dump_evpd_ascii(unsigned char *data, uint16_t data_len) { const uint16_t ascii_len = (data[0] << 8) | data[1]; bool not_in_string = true; uint16_t i; printf("ASCII len: %u\n", ascii_len); printf("ASCII data: \""); for (i = 2; i < ascii_len + 2; i++) putchar(data[i]); printf("\"\n"); for (; i < data_len; i++) { if (isprint(data[i])) { if (not_in_string) { printf("Vendor string: \""); not_in_string = false; } putchar(data[i]); } else { if (!not_in_string) { printf("\"\n"); not_in_string = true; } } } if (!not_in_string) printf("\"\n"); } static void dump_evpd(int fd, uint8_t page) { unsigned char cdb[32]; unsigned char buf[512] ; unsigned cdb_len = cdb_inquiry(cdb, true, page, sizeof(buf)); printf("\n\nExtended Inquiry Page %u (%02x):\n", page, page); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); if (buf_len < EVPD_MIN_LEN) { printf("Buffer returned is too small, got %d expected minimum of %d", buf_len, EVPD_MIN_LEN); return; } if (page >= 0x01 && page <= 0x7F) { dump_evpd_ascii(evpd_page_data(buf), evpd_page_len(buf)); } } static void do_extended_inquiry(int fd) { unsigned char cdb[32]; unsigned char buf[512] ; unsigned cdb_len = cdb_inquiry(cdb, true, 0, sizeof(buf)); printf("\n\nExtended Inquiry:\n"); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); if (buf_len < EVPD_MIN_LEN) { printf("Buffer returned is too small, got %d expected minimum of %d", buf_len, EVPD_MIN_LEN); return; } printf("Peripheral Qualifier: %u\n", evpd_peripheral_qualifier(buf)); printf("Peripheral Device Type: %u\n", evpd_peripheral_device_type(buf)); uint16_t max_page_idx = evpd_page_len(buf) + 4; uint16_t i; for (i = 4; i < max_page_idx; i++) dump_evpd(fd, buf[i]); } static void do_simple_inquiry(int fd) { unsigned char cdb[32]; unsigned char buf[512] ; unsigned cdb_len = cdb_inquiry_simple(cdb, 96); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); int device_type; scsi_vendor_t vendor; scsi_model_t model; scsi_fw_revision_t rev; scsi_serial_t serial; bool parsed = parse_inquiry(buf, buf_len, &device_type, vendor, model, rev, serial); if (!parsed) { printf("Failed to parse INQUIRY buffer\n"); return; } printf("Device Type: %d - %s\n", device_type, scsi_device_type_name(device_type)); printf("Vendor: %s\n", vendor); printf("Model: %s\n", model); printf("Rev: %s\n", rev); printf("Serial: %s\n", serial); } void do_command(int fd) { do_simple_inquiry(fd); do_extended_inquiry(fd); } diskscan-0.21/libscsicmd/test/scsi_log_sense.c000066400000000000000000000070351456470715000215070ustar00rootroot00000000000000/* Copyright 2014 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include "scsicmd_utils.h" #include "main.h" #include "sense_dump.h" #include #include #include #include #include #include #include #include #include static void dump_page(int fd, uint8_t page, uint8_t subpage) { unsigned char cdb[32]; unsigned char buf[16*1024]; unsigned cdb_len = cdb_log_sense(cdb, page, subpage, sizeof(buf)); printf("List page %02X subpage %02X\n", page, subpage); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); printf("\n"); } void do_command(int fd) { unsigned char cdb[32]; unsigned char buf[16*1024]; unsigned cdb_len = cdb_log_sense(cdb, 0, 0, sizeof(buf)); printf("List all supported pages\n"); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); if (buf_len < 4) { printf("log sense list must have at least 4 bytes\n"); return; } if (buf[0] != 0 || buf[1] != 0) { printf("expected to receive log page 0 subpage 0\n"); return; } uint16_t num_pages = get_uint16(buf, 2); uint16_t i; for (i = 0; i < num_pages; i++) { dump_page(fd, buf[4 + i], 0); } printf("List all pages and subpages\n"); cdb_len = cdb_log_sense(cdb, 0, 0xff, sizeof(buf)); ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } sense = NULL; sense_len = 0; buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); if (buf_len < 4) { printf("log sense list must have at least 4 bytes\n"); return; } if (buf[0] != 0x40 || buf[1] != 0xFF) { printf("expected to receive log page 0 (spf=1) subpage 0xFF\n"); return; } num_pages = get_uint16(buf, 2); for (i = 0; i < num_pages; i++) { uint8_t page = buf[4 + i*2] & 0x3F; uint8_t subpage = buf[4 + i*2 + 1]; if (subpage == 0) { printf("Skipping page %02X subpage %02X since subpage is 00 it was already retrieved above\n", page, subpage); continue; } dump_page(fd, page, subpage); } } diskscan-0.21/libscsicmd/test/scsi_mode_sense.c000066400000000000000000000056071456470715000216550ustar00rootroot00000000000000/* Copyright 2014 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include "main.h" #include "sense_dump.h" #include "parse_mode_sense.h" #include #include #include #include #include #include #include #include #include void do_command(int fd) { unsigned char cdb[32]; unsigned char buf[4096]; unsigned cdb_len = cdb_mode_sense_10(cdb, true, false, PAGE_CONTROL_CURRENT, 0x3F, 0xFF, sizeof(buf)); memset(buf, 0, sizeof(buf)); printf("List all supported pages\n"); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); if (buf_len < MODE_SENSE_10_MIN_LEN) { printf("Returned data is too short, expected a minimum of %u bytes and got only %u\n", MODE_SENSE_10_MIN_LEN, buf_len); return; } printf("Mode data len: %u\n", mode_sense_10_data_len(buf)); printf("Medium Type: %u\n", mode_sense_10_medium_type(buf)); printf("Device specific param: %u\n", mode_sense_10_device_specific_param(buf)); printf("Long LBA: %s\n", mode_sense_10_long_lba(buf) ? "yes" : "no"); printf("Block Descriptor length: %u\n", mode_sense_10_block_descriptor_length(buf)); if (buf_len < MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(buf)) { printf("Not enough data for the block descriptor length\n"); return; } if (mode_sense_10_long_lba(buf)) { printf("Don't know how to parse the block descriptor for a long lba yet\n"); } else { uint8_t *bdb = mode_sense_10_block_descriptor_data(buf); putchar('\n'); printf("Density code: %u\n", block_descriptor_density_code(bdb)); printf("Num blocks: %u\n", block_descriptor_num_blocks(bdb)); printf("Block length: %u\n", block_descriptor_block_length(bdb)); } if (buf_len < MODE_SENSE_10_MIN_LEN + mode_sense_10_block_descriptor_length(buf) + mode_sense_10_data_len(buf)) { printf("Not enough data for the mode data length\n"); return; } putchar('\n'); //uint8_t *mode_data = mode_sense_10_mode_data(buf); } diskscan-0.21/libscsicmd/test/scsi_read_capacity_10.c000066400000000000000000000031571456470715000226220ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include "main.h" #include #include #include #include #include #include #include #include #include void do_command(int fd) { unsigned char cdb[32]; unsigned char buf[512] ; unsigned cdb_len = cdb_read_capacity_10(cdb); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); uint32_t max_lba; uint32_t block_size; bool parsed = parse_read_capacity_10(buf, buf_len, &max_lba, &block_size); if (!parsed) { printf("Failed to parse read capacity buffer\n"); return; } printf("Max LBA: %u\nBlock size: %u\n", max_lba, block_size); return; } diskscan-0.21/libscsicmd/test/scsi_read_capacity_16.c000066400000000000000000000047241456470715000226310ustar00rootroot00000000000000/* Copyright 2013 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include "main.h" #include #include #include #include #include #include #include #include #include void do_command(int fd) { unsigned char cdb[32]; unsigned char buf[512] ; unsigned cdb_len = cdb_read_capacity_16(cdb, sizeof(buf)); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); uint64_t max_lba; uint32_t block_size; bool prot_enable; unsigned p_type; unsigned p_i_exponent; unsigned logical_blocks_per_physical_block_exponent; bool thin_provisioning_enabled; bool thin_provisioning_zero; unsigned lowest_aligned_lba; bool parsed = parse_read_capacity_16(buf, buf_len, &max_lba, &block_size, &prot_enable, &p_type, &p_i_exponent, &logical_blocks_per_physical_block_exponent, &thin_provisioning_enabled, &thin_provisioning_zero, &lowest_aligned_lba); if (!parsed) { printf("Failed to parse read capacity buffer\n"); return; } printf("Max LBA: %"PRIu64"\nBlock size: %u\n", max_lba, block_size); printf("Protection enabled: %s\n", prot_enable ? "true" : "false"); printf("Protection type: %u\n", p_type); printf("Protection exponent: %u\n", p_i_exponent); printf("LBAs per block exponent: %u\n", logical_blocks_per_physical_block_exponent); printf("Thin provisioning enabled: %s\n", thin_provisioning_enabled ? "true" : "false"); printf("Thin provisoning zeroes: %s\n", thin_provisioning_zero ? "true" : "false"); printf("Lowest aligned LBA: %u\n", lowest_aligned_lba); return; } diskscan-0.21/libscsicmd/test/scsi_receive_diagnostics.c000066400000000000000000000050271456470715000235410ustar00rootroot00000000000000/* Copyright 2014 Baruch Even * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ #include "scsicmd.h" #include "parse_receive_diagnostics.h" #include "main.h" #include "sense_dump.h" #include #include #include #include #include #include #include #include #include static void dump_page(int fd, uint8_t page) { unsigned char cdb[32]; unsigned char buf[16*1024]; unsigned cdb_len = cdb_receive_diagnostics(cdb, true, page, sizeof(buf)); printf("List page %02X\n", page); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); printf("\n"); } void do_command(int fd) { unsigned char cdb[32]; unsigned char buf[16*1024]; unsigned cdb_len = cdb_receive_diagnostics(cdb, true, 0, sizeof(buf)); printf("List all supported pages\n"); bool ret = submit_cmd(fd, cdb, cdb_len, buf, sizeof(buf), SG_DXFER_FROM_DEV); if (!ret) { fprintf(stderr, "Failed to submit command\n"); return; } unsigned char *sense = NULL; unsigned sense_len = 0; unsigned buf_len = 0; ret = read_response_buf(fd, &sense, &sense_len, &buf_len); if (sense) { printf("error while reading response buffer, nothing to show\n"); return; } printf("Read %u bytes\n", buf_len); response_dump(buf, buf_len); if (buf_len < RECV_DIAG_MIN_LEN) { printf("receive diagnostics list must have at least 4 bytes\n"); return; } if (recv_diag_get_page_code(buf) != 0) { printf("expected to receive receive diagnostics page 0\n"); return; } uint16_t num_pages = recv_diag_get_len(buf); uint16_t i; for (i = 0; i < num_pages; i++) { dump_page(fd, buf[4 + i]); } } diskscan-0.21/libscsicmd/test/sense_decode.c000066400000000000000000000033051456470715000211240ustar00rootroot00000000000000#include "sense_dump.h" #include #include int main(int argc, char **argv) { unsigned char sense[256]; int sense_len = 0; printf("Reading sense from args to buffer...\n"); int i; bool is_top_nibble = true; for (i = 1; i < argc; i++) { char *ch; for (ch = argv[i]; *ch != 0; ch++) { unsigned char val; if (*ch >= '0' && *ch <= '9') val = (*ch) - '0'; else if (*ch >= 'a' && *ch <= 'f') val = (*ch) - 'a' + 0xa; else if (*ch >= 'A' && *ch <= 'F') val = (*ch) - 'A' + 0xA; else if (*ch == ' ' || *ch == '+' || *ch == '\t') { continue; } else { fprintf(stderr, "\n\nInvalid character '%c' (%d) in sequence\n", *ch, *ch); return 1; } if (is_top_nibble) { sense[sense_len] = val<<4; is_top_nibble = false; } else { sense[sense_len] |= val; is_top_nibble = true; sense_len++; } } } if (!is_top_nibble) { fprintf(stderr, "Missing a nibble!\n"); return 2; } printf("Decoding sense...\n"); sense_dump(sense, sense_len); return 0; } diskscan-0.21/libscsicmd/test/sense_dump.c000066400000000000000000000107551456470715000206550ustar00rootroot00000000000000#include "sense_dump.h" #include "scsicmd.h" #include #include void cdb_dump(unsigned char *cdb, int cdb_len) { int i; printf("CDB: "); for (i = 0; i < cdb_len; i++) { printf("%02x ", cdb[i]); } printf("\n"); } void response_dump(unsigned char *buf, int buf_len) { int i; for (i = 0; i < buf_len; i++) { if (i % 16 == 0) printf("\n%02x ", i); printf("%02x ", buf[i]); } printf("\n"); } static bool print_bool(const char *name, bool val) { printf("%s: %s\n", name, val ? "yes" : "no"); return val; } static bool print_code(const char *name, bool val, const char *true_code, const char *false_code) { printf("%s: %s\n", name, val ? true_code : false_code); return val; } static void sense_dump_sense_info(sense_info_t *si) { print_code("Type", si->is_fixed, "Fixed", "Descriptor"); print_code("Time", si->is_current, "Current", "Deferred"); printf("Code: %x/%02x/%02x\n", si->sense_key, si->asc, si->ascq); printf("Code: %s/%s\n", sense_key_to_name(si->sense_key), asc_num_to_name(si->asc, si->ascq)); printf("Vendor Unique: 0x%04x\n", si->vendor_unique_error); if (si->information_valid) printf("Information: %"PRIx64"\n", si->information); if (si->cmd_specific_valid) printf("Command specific: %"PRIx64"\n", si->cmd_specific); if (si->sense_key_specific_valid) { switch (si->sense_key) { case SENSE_KEY_ILLEGAL_REQUEST: print_code("Illegal Request Type", si->sense_key_specific.illegal_request.command_error, "CDB", "Data"); if (si->sense_key_specific.illegal_request.bit_pointer_valid) printf("Illegal Request Bit: %d\n", si->sense_key_specific.illegal_request.bit_pointer); printf("Illegal Request Field: %d\n", si->sense_key_specific.illegal_request.field_pointer); break; case SENSE_KEY_HARDWARE_ERROR: case SENSE_KEY_MEDIUM_ERROR: case SENSE_KEY_RECOVERED_ERROR: printf("Actual Retry Count: %d\n", si->sense_key_specific.hardware_medium_recovered_error.actual_retry_count); break; case SENSE_KEY_NOT_READY: case SENSE_KEY_NO_SENSE: printf("Progress: %g%%\n", si->sense_key_specific.not_ready.progress); break; case SENSE_KEY_COPY_ABORTED: print_code("Copy Aborted Type", si->sense_key_specific.copy_aborted.segment_descriptor, "Segment", "Descriptor"); if (si->sense_key_specific.copy_aborted.bit_pointer_valid) printf("Copy Aborted Bit: %d\n", si->sense_key_specific.copy_aborted.bit_pointer); printf("Copy Aborted Field: %d\n", si->sense_key_specific.copy_aborted.field_pointer); break; case SENSE_KEY_UNIT_ATTENTION: print_bool("Unit Attention Overflow", si->sense_key_specific.unit_attention.overflow); break; } } if (si->fru_code_valid) printf("FRU Code: %02x\n", si->fru_code); if (si->ata_status_valid) { printf("ATA Status valid\n"); /*TODO: more details */ printf("ATA\n"); printf(" Extend: %02x\n", si->ata_status.extend); printf(" Error: %02x\n", si->ata_status.error); printf(" Device: %02x\n", si->ata_status.device); printf(" Status: %02x\n", si->ata_status.status); printf(" Sector Count: %u\n", si->ata_status.sector_count); printf(" LBA: %"PRIu64" / %"PRIx64"\n", si->ata_status.lba, si->ata_status.lba); } print_bool("Incorrect Length Indicator", si->incorrect_len_indicator); } void sense_dump(unsigned char *sense, int sense_len) { printf("Raw sense buffer:\n"); response_dump(sense, sense_len); printf("\n"); sense_info_t si; bool success = scsi_parse_sense(sense, sense_len, &si); printf("Parsing succeeded: %s\n", success ? "yes" : "no"); sense_dump_sense_info(&si); } diskscan-0.21/libscsicmd/test/sense_dump.h000066400000000000000000000003201456470715000206450ustar00rootroot00000000000000#ifndef _SENSE_DUMP_H #define _SENSE_DUMP_H void sense_dump(unsigned char *sense, int sense_len); void response_dump(unsigned char *buf, int buf_len); void cdb_dump(unsigned char *cdb, int cdb_len); #endif diskscan-0.21/progressbar/000077500000000000000000000000001456470715000155755ustar00rootroot00000000000000diskscan-0.21/progressbar/.gitignore000066400000000000000000000000401456470715000175570ustar00rootroot00000000000000demo doc/ *~ *.o *.so *.a *.swp diskscan-0.21/progressbar/Doxyfile000066400000000000000000002340471456470715000173150ustar00rootroot00000000000000# Doxyfile 1.8.3.1 # This file describes the settings to be used by the documentation system # doxygen (www.doxygen.org) for a project. # # All text after a hash (#) is considered a comment and will be ignored. # The format is: # TAG = value [value, ...] # For lists items can also be appended using: # TAG += value [value, ...] # Values that contain spaces should be placed between quotes (" "). #--------------------------------------------------------------------------- # Project related configuration options #--------------------------------------------------------------------------- # This tag specifies the encoding used for all characters in the config file # that follow. The default is UTF-8 which is also the encoding used for all # text before the first occurrence of this tag. Doxygen uses libiconv (or the # iconv built into libc) for the transcoding. See # http://www.gnu.org/software/libiconv for the list of possible encodings. DOXYFILE_ENCODING = UTF-8 # The PROJECT_NAME tag is a single word (or sequence of words) that should # identify the project. Note that if you do not use Doxywizard you need # to put quotes around the project name if it contains spaces. PROJECT_NAME = "Progressbar" # The PROJECT_NUMBER tag can be used to enter a project or revision number. # This could be handy for archiving the generated documentation or # if some version control system is used. PROJECT_NUMBER = # Using the PROJECT_BRIEF tag one can provide an optional one line description # for a project that appears at the top of each page and should give viewer # a quick idea about the purpose of the project. Keep the description short. PROJECT_BRIEF = # With the PROJECT_LOGO tag one can specify an logo or icon that is # included in the documentation. The maximum height of the logo should not # exceed 55 pixels and the maximum width should not exceed 200 pixels. # Doxygen will copy the logo to the output directory. PROJECT_LOGO = # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. # If a relative path is entered, it will be relative to the location # where doxygen was started. If left blank the current directory will be used. OUTPUT_DIRECTORY = doc/api # If the CREATE_SUBDIRS tag is set to YES, then doxygen will create # 4096 sub-directories (in 2 levels) under the output directory of each output # format and will distribute the generated files over these directories. # Enabling this option can be useful when feeding doxygen a huge amount of # source files, where putting all generated files in the same directory would # otherwise cause performance problems for the file system. CREATE_SUBDIRS = NO # The OUTPUT_LANGUAGE tag is used to specify the language in which all # documentation generated by doxygen is written. Doxygen will use this # information to generate all constant output in the proper language. # The default language is English, other supported languages are: # Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional, # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, # Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English # If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will # include brief member descriptions after the members that are listed in # the file and class documentation (similar to JavaDoc). # Set to NO to disable this. BRIEF_MEMBER_DESC = YES # If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend # the brief description of a member or function before the detailed description. # Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the # brief descriptions will be completely suppressed. REPEAT_BRIEF = YES # This tag implements a quasi-intelligent brief description abbreviator # that is used to form the text in various listings. Each string # in this list, if found as the leading text of the brief description, will be # stripped from the text and the result after processing the whole list, is # used as the annotated text. Otherwise, the brief description is used as-is. # If left blank, the following values are used ("$name" is automatically # replaced with the name of the entity): "The $name class" "The $name widget" # "The $name file" "is" "provides" "specifies" "contains" # "represents" "a" "an" "the" ABBREVIATE_BRIEF = # If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then # Doxygen will generate a detailed section even if there is only a brief # description. ALWAYS_DETAILED_SEC = NO # If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all # inherited members of a class in the documentation of that class as if those # members were ordinary class members. Constructors, destructors and assignment # operators of the base classes will not be shown. INLINE_INHERITED_MEMB = NO # If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full # path before files name in the file list and in the header files. If set # to NO the shortest path that makes the file name unique will be used. FULL_PATH_NAMES = YES # If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag # can be used to strip a user-defined part of the path. Stripping is # only done if one of the specified strings matches the left-hand part of # the path. The tag can be used to show relative paths in the file list. # If left blank the directory from which doxygen is run is used as the # path to strip. Note that you specify absolute paths here, but also # relative paths, which will be relative from the directory where doxygen is # started. STRIP_FROM_PATH = # The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of # the path mentioned in the documentation of a class, which tells # the reader which header file to include in order to use a class. # If left blank only the name of the header file containing the class # definition is used. Otherwise one should specify the include paths that # are normally passed to the compiler using the -I flag. STRIP_FROM_INC_PATH = # If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter # (but less readable) file names. This can be useful if your file system # doesn't support long names like on DOS, Mac, or CD-ROM. SHORT_NAMES = NO # If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen # will interpret the first line (until the first dot) of a JavaDoc-style # comment as the brief description. If set to NO, the JavaDoc # comments will behave just like regular Qt-style comments # (thus requiring an explicit @brief command for a brief description.) JAVADOC_AUTOBRIEF = NO # If the QT_AUTOBRIEF tag is set to YES then Doxygen will # interpret the first line (until the first dot) of a Qt-style # comment as the brief description. If set to NO, the comments # will behave just like regular Qt-style comments (thus requiring # an explicit \brief command for a brief description.) QT_AUTOBRIEF = NO # The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen # treat a multi-line C++ special comment block (i.e. a block of //! or /// # comments) as a brief description. This used to be the default behaviour. # The new default is to treat a multi-line C++ comment block as a detailed # description. Set this tag to YES if you prefer the old behaviour instead. MULTILINE_CPP_IS_BRIEF = NO # If the INHERIT_DOCS tag is set to YES (the default) then an undocumented # member inherits the documentation from any documented member that it # re-implements. INHERIT_DOCS = YES # If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce # a new page for each member. If set to NO, the documentation of a member will # be part of the file/class/namespace that contains it. SEPARATE_MEMBER_PAGES = NO # The TAB_SIZE tag can be used to set the number of spaces in a tab. # Doxygen uses this value to replace tabs by spaces in code fragments. TAB_SIZE = 8 # This tag can be used to specify a number of aliases that acts # as commands in the documentation. An alias has the form "name=value". # For example adding "sideeffect=\par Side Effects:\n" will allow you to # put the command \sideeffect (or @sideeffect) in the documentation, which # will result in a user-defined paragraph with heading "Side Effects:". # You can put \n's in the value part of an alias to insert newlines. ALIASES = # This tag can be used to specify a number of word-keyword mappings (TCL only). # A mapping has the form "name=value". For example adding # "class=itcl::class" will allow you to use the command class in the # itcl::class meaning. TCL_SUBST = # Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C # sources only. Doxygen will then generate output that is more tailored for C. # For instance, some of the names that are used will be different. The list # of all members will be omitted, etc. OPTIMIZE_OUTPUT_FOR_C = YES # Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java # sources only. Doxygen will then generate output that is more tailored for # Java. For instance, namespaces will be presented as packages, qualified # scopes will look different, etc. OPTIMIZE_OUTPUT_JAVA = NO # Set the OPTIMIZE_FOR_FORTRAN tag to YES if your project consists of Fortran # sources only. Doxygen will then generate output that is more tailored for # Fortran. OPTIMIZE_FOR_FORTRAN = NO # Set the OPTIMIZE_OUTPUT_VHDL tag to YES if your project consists of VHDL # sources. Doxygen will then generate output that is tailored for # VHDL. OPTIMIZE_OUTPUT_VHDL = NO # Doxygen selects the parser to use depending on the extension of the files it # parses. With this tag you can assign which parser to use for a given # extension. Doxygen has a built-in mapping, but you can override or extend it # using this tag. The format is ext=language, where ext is a file extension, # and language is one of the parsers supported by doxygen: IDL, Java, # Javascript, CSharp, C, C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, # C++. For instance to make doxygen treat .inc files as Fortran files (default # is PHP), and .f files as C (default is Fortran), use: inc=Fortran f=C. Note # that for custom extensions you also need to set FILE_PATTERNS otherwise the # files are not read by doxygen. EXTENSION_MAPPING = # If MARKDOWN_SUPPORT is enabled (the default) then doxygen pre-processes all # comments according to the Markdown format, which allows for more readable # documentation. See http://daringfireball.net/projects/markdown/ for details. # The output of markdown processing is further processed by doxygen, so you # can mix doxygen, HTML, and XML commands with Markdown formatting. # Disable only in case of backward compatibilities issues. MARKDOWN_SUPPORT = YES # When enabled doxygen tries to link words that correspond to documented classes, # or namespaces to their corresponding documentation. Such a link can be # prevented in individual cases by by putting a % sign in front of the word or # globally by setting AUTOLINK_SUPPORT to NO. AUTOLINK_SUPPORT = YES # If you use STL classes (i.e. std::string, std::vector, etc.) but do not want # to include (a tag file for) the STL sources as input, then you should # set this tag to YES in order to let doxygen match functions declarations and # definitions whose arguments contain STL classes (e.g. func(std::string); v.s. # func(std::string) {}). This also makes the inheritance and collaboration # diagrams that involve STL classes more complete and accurate. BUILTIN_STL_SUPPORT = NO # If you use Microsoft's C++/CLI language, you should set this option to YES to # enable parsing support. CPP_CLI_SUPPORT = NO # Set the SIP_SUPPORT tag to YES if your project consists of sip sources only. # Doxygen will parse them like normal C++ but will assume all classes use public # instead of private inheritance when no explicit protection keyword is present. SIP_SUPPORT = NO # For Microsoft's IDL there are propget and propput attributes to indicate # getter and setter methods for a property. Setting this option to YES (the # default) will make doxygen replace the get and set methods by a property in # the documentation. This will only work if the methods are indeed getting or # setting a simple type. If this is not the case, or you want to show the # methods anyway, you should set this option to NO. IDL_PROPERTY_SUPPORT = YES # If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC # tag is set to YES, then doxygen will reuse the documentation of the first # member in the group (if any) for the other members of the group. By default # all members of a group must be documented explicitly. DISTRIBUTE_GROUP_DOC = NO # Set the SUBGROUPING tag to YES (the default) to allow class member groups of # the same type (for instance a group of public functions) to be put as a # subgroup of that type (e.g. under the Public Functions section). Set it to # NO to prevent subgrouping. Alternatively, this can be done per class using # the \nosubgrouping command. SUBGROUPING = YES # When the INLINE_GROUPED_CLASSES tag is set to YES, classes, structs and # unions are shown inside the group in which they are included (e.g. using # @ingroup) instead of on a separate page (for HTML and Man pages) or # section (for LaTeX and RTF). INLINE_GROUPED_CLASSES = NO # When the INLINE_SIMPLE_STRUCTS tag is set to YES, structs, classes, and # unions with only public data fields will be shown inline in the documentation # of the scope in which they are defined (i.e. file, namespace, or group # documentation), provided this scope is documented. If set to NO (the default), # structs, classes, and unions are shown on a separate page (for HTML and Man # pages) or section (for LaTeX and RTF). INLINE_SIMPLE_STRUCTS = NO # When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct, union, or enum # is documented as struct, union, or enum with the name of the typedef. So # typedef struct TypeS {} TypeT, will appear in the documentation as a struct # with name TypeT. When disabled the typedef will appear as a member of a file, # namespace, or class. And the struct will be named TypeS. This can typically # be useful for C code in case the coding convention dictates that all compound # types are typedef'ed and only the typedef is referenced, never the tag name. TYPEDEF_HIDES_STRUCT = NO # The SYMBOL_CACHE_SIZE determines the size of the internal cache use to # determine which symbols to keep in memory and which to flush to disk. # When the cache is full, less often used symbols will be written to disk. # For small to medium size projects (<1000 input files) the default value is # probably good enough. For larger projects a too small cache size can cause # doxygen to be busy swapping symbols to and from disk most of the time # causing a significant performance penalty. # If the system has enough physical memory increasing the cache will improve the # performance by keeping more symbols in memory. Note that the value works on # a logarithmic scale so increasing the size by one will roughly double the # memory usage. The cache size is given by this formula: # 2^(16+SYMBOL_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. SYMBOL_CACHE_SIZE = 0 # Similar to the SYMBOL_CACHE_SIZE the size of the symbol lookup cache can be # set using LOOKUP_CACHE_SIZE. This cache is used to resolve symbols given # their name and scope. Since this can be an expensive process and often the # same symbol appear multiple times in the code, doxygen keeps a cache of # pre-resolved symbols. If the cache is too small doxygen will become slower. # If the cache is too large, memory is wasted. The cache size is given by this # formula: 2^(16+LOOKUP_CACHE_SIZE). The valid range is 0..9, the default is 0, # corresponding to a cache size of 2^16 = 65536 symbols. LOOKUP_CACHE_SIZE = 0 #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- # If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in # documentation are documented, even if no documentation was available. # Private class members and static file members will be hidden unless # the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES EXTRACT_ALL = NO # If the EXTRACT_PRIVATE tag is set to YES all private members of a class # will be included in the documentation. EXTRACT_PRIVATE = NO # If the EXTRACT_PACKAGE tag is set to YES all members with package or internal # scope will be included in the documentation. EXTRACT_PACKAGE = NO # If the EXTRACT_STATIC tag is set to YES all static members of a file # will be included in the documentation. EXTRACT_STATIC = NO # If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs) # defined locally in source files will be included in the documentation. # If set to NO only classes defined in header files are included. EXTRACT_LOCAL_CLASSES = YES # This flag is only useful for Objective-C code. When set to YES local # methods, which are defined in the implementation section but not in # the interface are included in the documentation. # If set to NO (the default) only methods in the interface are included. EXTRACT_LOCAL_METHODS = NO # If this flag is set to YES, the members of anonymous namespaces will be # extracted and appear in the documentation as a namespace called # 'anonymous_namespace{file}', where file will be replaced with the base # name of the file that contains the anonymous namespace. By default # anonymous namespaces are hidden. EXTRACT_ANON_NSPACES = NO # If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all # undocumented members of documented classes, files or namespaces. # If set to NO (the default) these members will be included in the # various overviews, but no documentation section is generated. # This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_MEMBERS = NO # If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all # undocumented classes that are normally visible in the class hierarchy. # If set to NO (the default) these classes will be included in the various # overviews. This option has no effect if EXTRACT_ALL is enabled. HIDE_UNDOC_CLASSES = NO # If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all # friend (class|struct|union) declarations. # If set to NO (the default) these declarations will be included in the # documentation. HIDE_FRIEND_COMPOUNDS = NO # If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any # documentation blocks found inside the body of a function. # If set to NO (the default) these blocks will be appended to the # function's detailed documentation block. HIDE_IN_BODY_DOCS = NO # The INTERNAL_DOCS tag determines if documentation # that is typed after a \internal command is included. If the tag is set # to NO (the default) then the documentation will be excluded. # Set it to YES to include the internal documentation. INTERNAL_DOCS = NO # If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate # file names in lower-case letters. If set to YES upper-case letters are also # allowed. This is useful if you have classes or files whose names only differ # in case and if your file system supports case sensitive file names. Windows # and Mac users are advised to set this option to NO. CASE_SENSE_NAMES = YES # If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen # will show members with their full class and namespace scopes in the # documentation. If set to YES the scope will be hidden. HIDE_SCOPE_NAMES = NO # If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen # will put a list of the files that are included by a file in the documentation # of that file. SHOW_INCLUDE_FILES = YES # If the FORCE_LOCAL_INCLUDES tag is set to YES then Doxygen # will list include files with double quotes in the documentation # rather than with sharp brackets. FORCE_LOCAL_INCLUDES = NO # If the INLINE_INFO tag is set to YES (the default) then a tag [inline] # is inserted in the documentation for inline members. INLINE_INFO = YES # If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen # will sort the (detailed) documentation of file and class members # alphabetically by member name. If set to NO the members will appear in # declaration order. SORT_MEMBER_DOCS = YES # If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the # brief documentation of file, namespace and class members alphabetically # by member name. If set to NO (the default) the members will appear in # declaration order. SORT_BRIEF_DOCS = NO # If the SORT_MEMBERS_CTORS_1ST tag is set to YES then doxygen # will sort the (brief and detailed) documentation of class members so that # constructors and destructors are listed first. If set to NO (the default) # the constructors will appear in the respective orders defined by # SORT_MEMBER_DOCS and SORT_BRIEF_DOCS. # This tag will be ignored for brief docs if SORT_BRIEF_DOCS is set to NO # and ignored for detailed docs if SORT_MEMBER_DOCS is set to NO. SORT_MEMBERS_CTORS_1ST = NO # If the SORT_GROUP_NAMES tag is set to YES then doxygen will sort the # hierarchy of group names into alphabetical order. If set to NO (the default) # the group names will appear in their defined order. SORT_GROUP_NAMES = NO # If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be # sorted by fully-qualified names, including namespaces. If set to # NO (the default), the class list will be sorted only by class name, # not including the namespace part. # Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES. # Note: This option applies only to the class list, not to the # alphabetical list. SORT_BY_SCOPE_NAME = NO # If the STRICT_PROTO_MATCHING option is enabled and doxygen fails to # do proper type resolution of all parameters of a function it will reject a # match between the prototype and the implementation of a member function even # if there is only one candidate or it is obvious which candidate to choose # by doing a simple string match. By disabling STRICT_PROTO_MATCHING doxygen # will still accept a match between prototype and implementation in such cases. STRICT_PROTO_MATCHING = NO # The GENERATE_TODOLIST tag can be used to enable (YES) or # disable (NO) the todo list. This list is created by putting \todo # commands in the documentation. GENERATE_TODOLIST = YES # The GENERATE_TESTLIST tag can be used to enable (YES) or # disable (NO) the test list. This list is created by putting \test # commands in the documentation. GENERATE_TESTLIST = YES # The GENERATE_BUGLIST tag can be used to enable (YES) or # disable (NO) the bug list. This list is created by putting \bug # commands in the documentation. GENERATE_BUGLIST = YES # The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or # disable (NO) the deprecated list. This list is created by putting # \deprecated commands in the documentation. GENERATE_DEPRECATEDLIST= YES # The ENABLED_SECTIONS tag can be used to enable conditional # documentation sections, marked by \if section-label ... \endif # and \cond section-label ... \endcond blocks. ENABLED_SECTIONS = # The MAX_INITIALIZER_LINES tag determines the maximum number of lines # the initial value of a variable or macro consists of for it to appear in # the documentation. If the initializer consists of more lines than specified # here it will be hidden. Use a value of 0 to hide initializers completely. # The appearance of the initializer of individual variables and macros in the # documentation can be controlled using \showinitializer or \hideinitializer # command in the documentation regardless of this setting. MAX_INITIALIZER_LINES = 30 # Set the SHOW_USED_FILES tag to NO to disable the list of files generated # at the bottom of the documentation of classes and structs. If set to YES the # list will mention the files that were used to generate the documentation. SHOW_USED_FILES = YES # Set the SHOW_FILES tag to NO to disable the generation of the Files page. # This will remove the Files entry from the Quick Index and from the # Folder Tree View (if specified). The default is YES. SHOW_FILES = YES # Set the SHOW_NAMESPACES tag to NO to disable the generation of the # Namespaces page. # This will remove the Namespaces entry from the Quick Index # and from the Folder Tree View (if specified). The default is YES. SHOW_NAMESPACES = YES # The FILE_VERSION_FILTER tag can be used to specify a program or script that # doxygen should invoke to get the current version for each file (typically from # the version control system). Doxygen will invoke the program by executing (via # popen()) the command , where is the value of # the FILE_VERSION_FILTER tag, and is the name of an input file # provided by doxygen. Whatever the program writes to standard output # is used as the file version. See the manual for examples. FILE_VERSION_FILTER = # The LAYOUT_FILE tag can be used to specify a layout file which will be parsed # by doxygen. The layout file controls the global structure of the generated # output files in an output format independent way. To create the layout file # that represents doxygen's defaults, run doxygen with the -l option. # You can optionally specify a file name after the option, if omitted # DoxygenLayout.xml will be used as the name of the layout file. LAYOUT_FILE = # The CITE_BIB_FILES tag can be used to specify one or more bib files # containing the references data. This must be a list of .bib files. The # .bib extension is automatically appended if omitted. Using this command # requires the bibtex tool to be installed. See also # http://en.wikipedia.org/wiki/BibTeX for more info. For LaTeX the style # of the bibliography can be controlled using LATEX_BIB_STYLE. To use this # feature you need bibtex and perl available in the search path. Do not use # file names with spaces, bibtex cannot handle them. CITE_BIB_FILES = #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- # The QUIET tag can be used to turn on/off the messages that are generated # by doxygen. Possible values are YES and NO. If left blank NO is used. QUIET = NO # The WARNINGS tag can be used to turn on/off the warning messages that are # generated by doxygen. Possible values are YES and NO. If left blank # NO is used. WARNINGS = YES # If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings # for undocumented members. If EXTRACT_ALL is set to YES then this flag will # automatically be disabled. WARN_IF_UNDOCUMENTED = YES # If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for # potential errors in the documentation, such as not documenting some # parameters in a documented function, or documenting parameters that # don't exist or using markup commands wrongly. WARN_IF_DOC_ERROR = YES # The WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of # documentation. WARN_NO_PARAMDOC = NO # The WARN_FORMAT tag determines the format of the warning messages that # doxygen can produce. The string should contain the $file, $line, and $text # tags, which will be replaced by the file and line number from which the # warning originated and the warning text. Optionally the format may contain # $version, which will be replaced by the version of the file (if it could # be obtained via FILE_VERSION_FILTER) WARN_FORMAT = "$file:$line: $text" # The WARN_LOGFILE tag can be used to specify a file to which warning # and error messages should be written. If left blank the output is written # to stderr. WARN_LOGFILE = #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- # The INPUT tag can be used to specify the files and/or directories that contain # documented source files. You may enter file names like "myfile.cpp" or # directories like "/usr/src/myproject". Separate the files or directories # with spaces. INPUT = lib include test # This tag can be used to specify the character encoding of the source files # that doxygen parses. Internally doxygen uses the UTF-8 encoding, which is # also the default input encoding. Doxygen uses libiconv (or the iconv built # into libc) for the transcoding. See http://www.gnu.org/software/libiconv for # the list of possible encodings. INPUT_ENCODING = UTF-8 # If the value of the INPUT tag contains directories, you can use the # FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank the following patterns are tested: # *.c *.cc *.cxx *.cpp *.c++ *.d *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh # *.hxx *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.dox *.py # *.f90 *.f *.for *.vhd *.vhdl FILE_PATTERNS = *.c *.h # The RECURSIVE tag can be used to turn specify whether or not subdirectories # should be searched for input files as well. Possible values are YES and NO. # If left blank NO is used. RECURSIVE = NO # The EXCLUDE tag can be used to specify files and/or directories that should be # excluded from the INPUT source files. This way you can easily exclude a # subdirectory from a directory tree whose root is specified with the INPUT tag. # Note that relative paths are relative to the directory from which doxygen is # run. EXCLUDE = # The EXCLUDE_SYMLINKS tag can be used to select whether or not files or # directories that are symbolic links (a Unix file system feature) are excluded # from the input. EXCLUDE_SYMLINKS = NO # If the value of the INPUT tag contains directories, you can use the # EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude # certain files from those directories. Note that the wildcards are matched # against the file with absolute path, so to exclude all test directories # for example use the pattern */test/* EXCLUDE_PATTERNS = # The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names # (namespaces, classes, functions, etc.) that should be excluded from the # output. The symbol name can be a fully qualified name, a word, or if the # wildcard * is used, a substring. Examples: ANamespace, AClass, # AClass::ANamespace, ANamespace::*Test EXCLUDE_SYMBOLS = # The EXAMPLE_PATH tag can be used to specify one or more files or # directories that contain example code fragments that are included (see # the \include command). EXAMPLE_PATH = # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp # and *.h) to filter out the source-files in the directories. If left # blank all files are included. EXAMPLE_PATTERNS = # If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be # searched for input files to be used with the \include or \dontinclude # commands irrespective of the value of the RECURSIVE tag. # Possible values are YES and NO. If left blank NO is used. EXAMPLE_RECURSIVE = NO # The IMAGE_PATH tag can be used to specify one or more files or # directories that contain image that are included in the documentation (see # the \image command). IMAGE_PATH = # The INPUT_FILTER tag can be used to specify a program that doxygen should # invoke to filter for each input file. Doxygen will invoke the filter program # by executing (via popen()) the command , where # is the value of the INPUT_FILTER tag, and is the name of an # input file. Doxygen will then use the output that the filter program writes # to standard output. # If FILTER_PATTERNS is specified, this tag will be # ignored. INPUT_FILTER = # The FILTER_PATTERNS tag can be used to specify filters on a per file pattern # basis. # Doxygen will compare the file name with each pattern and apply the # filter if there is a match. # The filters are a list of the form: # pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further # info on how filters are used. If FILTER_PATTERNS is empty or if # non of the patterns match the file name, INPUT_FILTER is applied. FILTER_PATTERNS = # If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using # INPUT_FILTER) will be used to filter the input files when producing source # files to browse (i.e. when SOURCE_BROWSER is set to YES). FILTER_SOURCE_FILES = NO # The FILTER_SOURCE_PATTERNS tag can be used to specify source filters per file # pattern. A pattern will override the setting for FILTER_PATTERN (if any) # and it is also possible to disable source filtering for a specific pattern # using *.ext= (so without naming a filter). This option only has effect when # FILTER_SOURCE_FILES is enabled. FILTER_SOURCE_PATTERNS = # If the USE_MD_FILE_AS_MAINPAGE tag refers to the name of a markdown file that # is part of the input, its contents will be placed on the main page (index.html). # This can be useful if you have a project on for instance GitHub and want reuse # the introduction page also for the doxygen output. USE_MDFILE_AS_MAINPAGE = #--------------------------------------------------------------------------- # configuration options related to source browsing #--------------------------------------------------------------------------- # If the SOURCE_BROWSER tag is set to YES then a list of source files will # be generated. Documented entities will be cross-referenced with these sources. # Note: To get rid of all source code in the generated output, make sure also # VERBATIM_HEADERS is set to NO. SOURCE_BROWSER = NO # Setting the INLINE_SOURCES tag to YES will include the body # of functions and classes directly in the documentation. INLINE_SOURCES = NO # Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct # doxygen to hide any special comment blocks from generated source code # fragments. Normal C, C++ and Fortran comments will always remain visible. STRIP_CODE_COMMENTS = YES # If the REFERENCED_BY_RELATION tag is set to YES # then for each documented function all documented # functions referencing it will be listed. REFERENCED_BY_RELATION = YES # If the REFERENCES_RELATION tag is set to YES # then for each documented function all documented entities # called/used by that function will be listed. REFERENCES_RELATION = YES # If the REFERENCES_LINK_SOURCE tag is set to YES (the default) # and SOURCE_BROWSER tag is set to YES, then the hyperlinks from # functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will # link to the source code. # Otherwise they will link to the documentation. REFERENCES_LINK_SOURCE = YES # If the USE_HTAGS tag is set to YES then the references to source code # will point to the HTML generated by the htags(1) tool instead of doxygen # built-in source browser. The htags tool is part of GNU's global source # tagging system (see http://www.gnu.org/software/global/global.html). You # will need version 4.8.6 or higher. USE_HTAGS = NO # If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen # will generate a verbatim copy of the header file for each class for # which an include is specified. Set to NO to disable this. VERBATIM_HEADERS = YES #--------------------------------------------------------------------------- # configuration options related to the alphabetical class index #--------------------------------------------------------------------------- # If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index # of all compounds will be generated. Enable this if the project # contains a lot of classes, structs, unions or interfaces. ALPHABETICAL_INDEX = NO # If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then # the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns # in which this list will be split (can be a number in the range [1..20]) COLS_IN_ALPHA_INDEX = 5 # In case all classes in a project start with a common prefix, all # classes will be put under the same header in the alphabetical index. # The IGNORE_PREFIX tag can be used to specify one or more prefixes that # should be ignored while generating the index headers. IGNORE_PREFIX = #--------------------------------------------------------------------------- # configuration options related to the HTML output #--------------------------------------------------------------------------- # If the GENERATE_HTML tag is set to YES (the default) Doxygen will # generate HTML output. GENERATE_HTML = YES # The HTML_OUTPUT tag is used to specify where the HTML docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `html' will be used as the default path. HTML_OUTPUT = html # The HTML_FILE_EXTENSION tag can be used to specify the file extension for # each generated HTML page (for example: .htm,.php,.asp). If it is left blank # doxygen will generate files with .html extension. HTML_FILE_EXTENSION = .html # The HTML_HEADER tag can be used to specify a personal HTML header for # each generated HTML page. If it is left blank doxygen will generate a # standard header. Note that when using a custom header you are responsible # for the proper inclusion of any scripts and style sheets that doxygen # needs, which is dependent on the configuration options used. # It is advised to generate a default header using "doxygen -w html # header.html footer.html stylesheet.css YourConfigFile" and then modify # that header. Note that the header is subject to change so you typically # have to redo this when upgrading to a newer version of doxygen or when # changing the value of configuration settings such as GENERATE_TREEVIEW! HTML_HEADER = # The HTML_FOOTER tag can be used to specify a personal HTML footer for # each generated HTML page. If it is left blank doxygen will generate a # standard footer. HTML_FOOTER = # The HTML_STYLESHEET tag can be used to specify a user-defined cascading # style sheet that is used by each HTML page. It can be used to # fine-tune the look of the HTML output. If left blank doxygen will # generate a default style sheet. Note that it is recommended to use # HTML_EXTRA_STYLESHEET instead of this one, as it is more robust and this # tag will in the future become obsolete. HTML_STYLESHEET = # The HTML_EXTRA_STYLESHEET tag can be used to specify an additional # user-defined cascading style sheet that is included after the standard # style sheets created by doxygen. Using this option one can overrule # certain style aspects. This is preferred over using HTML_STYLESHEET # since it does not replace the standard style sheet and is therefor more # robust against future updates. Doxygen will copy the style sheet file to # the output directory. HTML_EXTRA_STYLESHEET = # The HTML_EXTRA_FILES tag can be used to specify one or more extra images or # other source files which should be copied to the HTML output directory. Note # that these files will be copied to the base HTML output directory. Use the # $relpath$ marker in the HTML_HEADER and/or HTML_FOOTER files to load these # files. In the HTML_STYLESHEET file, use the file name only. Also note that # the files will be copied as-is; there are no commands or markers available. HTML_EXTRA_FILES = # The HTML_COLORSTYLE_HUE tag controls the color of the HTML output. # Doxygen will adjust the colors in the style sheet and background images # according to this color. Hue is specified as an angle on a colorwheel, # see http://en.wikipedia.org/wiki/Hue for more information. # For instance the value 0 represents red, 60 is yellow, 120 is green, # 180 is cyan, 240 is blue, 300 purple, and 360 is red again. # The allowed range is 0 to 359. HTML_COLORSTYLE_HUE = 220 # The HTML_COLORSTYLE_SAT tag controls the purity (or saturation) of # the colors in the HTML output. For a value of 0 the output will use # grayscales only. A value of 255 will produce the most vivid colors. HTML_COLORSTYLE_SAT = 100 # The HTML_COLORSTYLE_GAMMA tag controls the gamma correction applied to # the luminance component of the colors in the HTML output. Values below # 100 gradually make the output lighter, whereas values above 100 make # the output darker. The value divided by 100 is the actual gamma applied, # so 80 represents a gamma of 0.8, The value 220 represents a gamma of 2.2, # and 100 does not change the gamma. HTML_COLORSTYLE_GAMMA = 80 # If the HTML_TIMESTAMP tag is set to YES then the footer of each generated HTML # page will contain the date and time when the page was generated. Setting # this to NO can help when comparing the output of multiple runs. HTML_TIMESTAMP = YES # If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML # documentation will contain sections that can be hidden and shown after the # page has loaded. HTML_DYNAMIC_SECTIONS = NO # With HTML_INDEX_NUM_ENTRIES one can control the preferred number of # entries shown in the various tree structured indices initially; the user # can expand and collapse entries dynamically later on. Doxygen will expand # the tree to such a level that at most the specified number of entries are # visible (unless a fully collapsed tree already exceeds this amount). # So setting the number of entries 1 will produce a full collapsed tree by # default. 0 is a special value representing an infinite number of entries # and will result in a full expanded tree by default. HTML_INDEX_NUM_ENTRIES = 100 # If the GENERATE_DOCSET tag is set to YES, additional index files # will be generated that can be used as input for Apple's Xcode 3 # integrated development environment, introduced with OSX 10.5 (Leopard). # To create a documentation set, doxygen will generate a Makefile in the # HTML output directory. Running make will produce the docset in that # directory and running "make install" will install the docset in # ~/Library/Developer/Shared/Documentation/DocSets so that Xcode will find # it at startup. # See http://developer.apple.com/tools/creatingdocsetswithdoxygen.html # for more information. GENERATE_DOCSET = NO # When GENERATE_DOCSET tag is set to YES, this tag determines the name of the # feed. A documentation feed provides an umbrella under which multiple # documentation sets from a single provider (such as a company or product suite) # can be grouped. DOCSET_FEEDNAME = "Doxygen generated docs" # When GENERATE_DOCSET tag is set to YES, this tag specifies a string that # should uniquely identify the documentation set bundle. This should be a # reverse domain-name style string, e.g. com.mycompany.MyDocSet. Doxygen # will append .docset to the name. DOCSET_BUNDLE_ID = org.doxygen.Project # When GENERATE_PUBLISHER_ID tag specifies a string that should uniquely # identify the documentation publisher. This should be a reverse domain-name # style string, e.g. com.mycompany.MyDocSet.documentation. DOCSET_PUBLISHER_ID = org.doxygen.Publisher # The GENERATE_PUBLISHER_NAME tag identifies the documentation publisher. DOCSET_PUBLISHER_NAME = Publisher # If the GENERATE_HTMLHELP tag is set to YES, additional index files # will be generated that can be used as input for tools like the # Microsoft HTML help workshop to generate a compiled HTML help file (.chm) # of the generated HTML documentation. GENERATE_HTMLHELP = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can # be used to specify the file name of the resulting .chm file. You # can add a path in front of the file if the result should not be # written to the html output directory. CHM_FILE = # If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can # be used to specify the location (absolute path including file name) of # the HTML help compiler (hhc.exe). If non-empty doxygen will try to run # the HTML help compiler on the generated index.hhp. HHC_LOCATION = # If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag # controls if a separate .chi index file is generated (YES) or that # it should be included in the master .chm file (NO). GENERATE_CHI = NO # If the GENERATE_HTMLHELP tag is set to YES, the CHM_INDEX_ENCODING # is used to encode HtmlHelp index (hhk), content (hhc) and project file # content. CHM_INDEX_ENCODING = # If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag # controls whether a binary table of contents is generated (YES) or a # normal table of contents (NO) in the .chm file. BINARY_TOC = NO # The TOC_EXPAND flag can be set to YES to add extra items for group members # to the contents of the HTML help documentation and to the tree view. TOC_EXPAND = NO # If the GENERATE_QHP tag is set to YES and both QHP_NAMESPACE and # QHP_VIRTUAL_FOLDER are set, an additional index file will be generated # that can be used as input for Qt's qhelpgenerator to generate a # Qt Compressed Help (.qch) of the generated HTML documentation. GENERATE_QHP = NO # If the QHG_LOCATION tag is specified, the QCH_FILE tag can # be used to specify the file name of the resulting .qch file. # The path specified is relative to the HTML output folder. QCH_FILE = # The QHP_NAMESPACE tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#namespace QHP_NAMESPACE = org.doxygen.Project # The QHP_VIRTUAL_FOLDER tag specifies the namespace to use when generating # Qt Help Project output. For more information please see # http://doc.trolltech.com/qthelpproject.html#virtual-folders QHP_VIRTUAL_FOLDER = doc # If QHP_CUST_FILTER_NAME is set, it specifies the name of a custom filter to # add. For more information please see # http://doc.trolltech.com/qthelpproject.html#custom-filters QHP_CUST_FILTER_NAME = # The QHP_CUST_FILT_ATTRS tag specifies the list of the attributes of the # custom filter to add. For more information please see # # Qt Help Project / Custom Filters. QHP_CUST_FILTER_ATTRS = # The QHP_SECT_FILTER_ATTRS tag specifies the list of the attributes this # project's # filter section matches. # # Qt Help Project / Filter Attributes. QHP_SECT_FILTER_ATTRS = # If the GENERATE_QHP tag is set to YES, the QHG_LOCATION tag can # be used to specify the location of Qt's qhelpgenerator. # If non-empty doxygen will try to run qhelpgenerator on the generated # .qhp file. QHG_LOCATION = # If the GENERATE_ECLIPSEHELP tag is set to YES, additional index files # will be generated, which together with the HTML files, form an Eclipse help # plugin. To install this plugin and make it available under the help contents # menu in Eclipse, the contents of the directory containing the HTML and XML # files needs to be copied into the plugins directory of eclipse. The name of # the directory within the plugins directory should be the same as # the ECLIPSE_DOC_ID value. After copying Eclipse needs to be restarted before # the help appears. GENERATE_ECLIPSEHELP = NO # A unique identifier for the eclipse help plugin. When installing the plugin # the directory name containing the HTML and XML files should also have # this name. ECLIPSE_DOC_ID = org.doxygen.Project # The DISABLE_INDEX tag can be used to turn on/off the condensed index (tabs) # at top of each HTML page. The value NO (the default) enables the index and # the value YES disables it. Since the tabs have the same information as the # navigation tree you can set this option to NO if you already set # GENERATE_TREEVIEW to YES. DISABLE_INDEX = NO # The GENERATE_TREEVIEW tag is used to specify whether a tree-like index # structure should be generated to display hierarchical information. # If the tag value is set to YES, a side panel will be generated # containing a tree-like index structure (just like the one that # is generated for HTML Help). For this to work a browser that supports # JavaScript, DHTML, CSS and frames is required (i.e. any modern browser). # Windows users are probably better off using the HTML help feature. # Since the tree basically has the same information as the tab index you # could consider to set DISABLE_INDEX to NO when enabling this option. GENERATE_TREEVIEW = NO # The ENUM_VALUES_PER_LINE tag can be used to set the number of enum values # (range [0,1..20]) that doxygen will group on one line in the generated HTML # documentation. Note that a value of 0 will completely suppress the enum # values from appearing in the overview section. ENUM_VALUES_PER_LINE = 4 # If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be # used to set the initial width (in pixels) of the frame in which the tree # is shown. TREEVIEW_WIDTH = 250 # When the EXT_LINKS_IN_WINDOW option is set to YES doxygen will open # links to external symbols imported via tag files in a separate window. EXT_LINKS_IN_WINDOW = NO # Use this tag to change the font size of Latex formulas included # as images in the HTML documentation. The default is 10. Note that # when you change the font size after a successful doxygen run you need # to manually remove any form_*.png images from the HTML output directory # to force them to be regenerated. FORMULA_FONTSIZE = 10 # Use the FORMULA_TRANPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files # in the HTML output before the changes have effect. FORMULA_TRANSPARENT = YES # Enable the USE_MATHJAX option to render LaTeX formulas using MathJax # (see http://www.mathjax.org) which uses client side Javascript for the # rendering instead of using prerendered bitmaps. Use this if you do not # have LaTeX installed or if you want to formulas look prettier in the HTML # output. When enabled you may also need to install MathJax separately and # configure the path to it using the MATHJAX_RELPATH option. USE_MATHJAX = YES # When MathJax is enabled you can set the default output format to be used for # thA MathJax output. Supported types are HTML-CSS, NativeMML (i.e. MathML) and # SVG. The default value is HTML-CSS, which is slower, but has the best # compatibility. MATHJAX_FORMAT = HTML-CSS # When MathJax is enabled you need to specify the location relative to the # HTML output directory using the MATHJAX_RELPATH option. The destination # directory should contain the MathJax.js script. For instance, if the mathjax # directory is located at the same level as the HTML output directory, then # MATHJAX_RELPATH should be ../mathjax. The default value points to # the MathJax Content Delivery Network so you can quickly see the result without # installing MathJax. # However, it is strongly recommended to install a local # copy of MathJax from http://www.mathjax.org before deployment. MATHJAX_RELPATH = http://cdn.mathjax.org/mathjax/latest # The MATHJAX_EXTENSIONS tag can be used to specify one or MathJax extension # names that should be enabled during MathJax rendering. MATHJAX_EXTENSIONS = # When the SEARCHENGINE tag is enabled doxygen will generate a search box # for the HTML output. The underlying search engine uses javascript # and DHTML and should work on any modern browser. Note that when using # HTML help (GENERATE_HTMLHELP), Qt help (GENERATE_QHP), or docsets # (GENERATE_DOCSET) there is already a search function so this one should # typically be disabled. For large projects the javascript based search engine # can be slow, then enabling SERVER_BASED_SEARCH may provide a better solution. SEARCHENGINE = NO # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a web server instead of a web client using Javascript. # There are two flavours of web server based search depending on the # EXTERNAL_SEARCH setting. When disabled, doxygen will generate a PHP script for # searching and an index file used by the script. When EXTERNAL_SEARCH is # enabled the indexing and searching needs to be provided by external tools. # See the manual for details. SERVER_BASED_SEARCH = NO # When EXTERNAL_SEARCH is enabled doxygen will no longer generate the PHP # script for searching. Instead the search results are written to an XML file # which needs to be processed by an external indexer. Doxygen will invoke an # external search engine pointed to by the SEARCHENGINE_URL option to obtain # the search results. Doxygen ships with an example indexer (doxyindexer) and # search engine (doxysearch.cgi) which are based on the open source search engine # library Xapian. See the manual for configuration details. EXTERNAL_SEARCH = NO # The SEARCHENGINE_URL should point to a search engine hosted by a web server # which will returned the search results when EXTERNAL_SEARCH is enabled. # Doxygen ships with an example search engine (doxysearch) which is based on # the open source search engine library Xapian. See the manual for configuration # details. SEARCHENGINE_URL = # When SERVER_BASED_SEARCH and EXTERNAL_SEARCH are both enabled the unindexed # search data is written to a file for indexing by an external tool. With the # SEARCHDATA_FILE tag the name of this file can be specified. SEARCHDATA_FILE = searchdata.xml # When SERVER_BASED_SEARCH AND EXTERNAL_SEARCH are both enabled the # EXTERNAL_SEARCH_ID tag can be used as an identifier for the project. This is # useful in combination with EXTRA_SEARCH_MAPPINGS to search through multiple # projects and redirect the results back to the right project. EXTERNAL_SEARCH_ID = # The EXTRA_SEARCH_MAPPINGS tag can be used to enable searching through doxygen # projects other than the one defined by this configuration file, but that are # all added to the same external search index. Each project needs to have a # unique id set via EXTERNAL_SEARCH_ID. The search mapping then maps the id # of to a relative location where the documentation can be found. # The format is: EXTRA_SEARCH_MAPPINGS = id1=loc1 id2=loc2 ... EXTRA_SEARCH_MAPPINGS = #--------------------------------------------------------------------------- # configuration options related to the LaTeX output #--------------------------------------------------------------------------- # If the GENERATE_LATEX tag is set to YES (the default) Doxygen will # generate Latex output. GENERATE_LATEX = YES # The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `latex' will be used as the default path. LATEX_OUTPUT = latex # The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be # invoked. If left blank `latex' will be used as the default command name. # Note that when enabling USE_PDFLATEX this option is only used for # generating bitmaps for formulas in the HTML output, but not in the # Makefile that is written to the output directory. LATEX_CMD_NAME = latex # The MAKEINDEX_CMD_NAME tag can be used to specify the command name to # generate index for LaTeX. If left blank `makeindex' will be used as the # default command name. MAKEINDEX_CMD_NAME = makeindex # If the COMPACT_LATEX tag is set to YES Doxygen generates more compact # LaTeX documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_LATEX = YES # The PAPER_TYPE tag can be used to set the paper type that is used # by the printer. Possible values are: a4, letter, legal and # executive. If left blank a4wide will be used. PAPER_TYPE = a4 # The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX # packages that should be included in the LaTeX output. EXTRA_PACKAGES = # The LATEX_HEADER tag can be used to specify a personal LaTeX header for # the generated latex document. The header should contain everything until # the first chapter. If it is left blank doxygen will generate a # standard header. Notice: only use this tag if you know what you are doing! LATEX_HEADER = # The LATEX_FOOTER tag can be used to specify a personal LaTeX footer for # the generated latex document. The footer should contain everything after # the last chapter. If it is left blank doxygen will generate a # standard footer. Notice: only use this tag if you know what you are doing! LATEX_FOOTER = # If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated # is prepared for conversion to pdf (using ps2pdf). The pdf file will # contain links (just like the HTML output) instead of page references # This makes the output suitable for online browsing using a pdf viewer. PDF_HYPERLINKS = YES # If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of # plain latex in the generated Makefile. Set this option to YES to get a # higher quality PDF documentation. USE_PDFLATEX = YES # If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode. # command to the generated LaTeX files. This will instruct LaTeX to keep # running if errors occur, instead of asking the user for help. # This option is also used when generating formulas in HTML. LATEX_BATCHMODE = NO # If LATEX_HIDE_INDICES is set to YES then doxygen will not # include the index chapters (such as File Index, Compound Index, etc.) # in the output. LATEX_HIDE_INDICES = NO # If LATEX_SOURCE_CODE is set to YES then doxygen will include # source code with syntax highlighting in the LaTeX output. # Note that which sources are shown also depends on other settings # such as SOURCE_BROWSER. LATEX_SOURCE_CODE = NO # The LATEX_BIB_STYLE tag can be used to specify the style to use for the # bibliography, e.g. plainnat, or ieeetr. The default style is "plain". See # http://en.wikipedia.org/wiki/BibTeX for more info. LATEX_BIB_STYLE = plain #--------------------------------------------------------------------------- # configuration options related to the RTF output #--------------------------------------------------------------------------- # If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output # The RTF output is optimized for Word 97 and may not look very pretty with # other RTF readers or editors. GENERATE_RTF = NO # The RTF_OUTPUT tag is used to specify where the RTF docs will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `rtf' will be used as the default path. RTF_OUTPUT = rtf # If the COMPACT_RTF tag is set to YES Doxygen generates more compact # RTF documents. This may be useful for small projects and may help to # save some trees in general. COMPACT_RTF = NO # If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated # will contain hyperlink fields. The RTF file will # contain links (just like the HTML output) instead of page references. # This makes the output suitable for online browsing using WORD or other # programs which support those fields. # Note: wordpad (write) and others do not support links. RTF_HYPERLINKS = NO # Load style sheet definitions from file. Syntax is similar to doxygen's # config file, i.e. a series of assignments. You only have to provide # replacements, missing definitions are set to their default value. RTF_STYLESHEET_FILE = # Set optional variables used in the generation of an rtf document. # Syntax is similar to doxygen's config file. RTF_EXTENSIONS_FILE = #--------------------------------------------------------------------------- # configuration options related to the man page output #--------------------------------------------------------------------------- # If the GENERATE_MAN tag is set to YES (the default) Doxygen will # generate man pages GENERATE_MAN = NO # The MAN_OUTPUT tag is used to specify where the man pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `man' will be used as the default path. MAN_OUTPUT = man # The MAN_EXTENSION tag determines the extension that is added to # the generated man pages (default is the subroutine's section .3) MAN_EXTENSION = .3 # If the MAN_LINKS tag is set to YES and Doxygen generates man output, # then it will generate one additional man file for each entity # documented in the real man page(s). These additional files # only source the real man page, but without them the man command # would be unable to find the correct page. The default is NO. MAN_LINKS = NO #--------------------------------------------------------------------------- # configuration options related to the XML output #--------------------------------------------------------------------------- # If the GENERATE_XML tag is set to YES Doxygen will # generate an XML file that captures the structure of # the code including all documentation. GENERATE_XML = NO # The XML_OUTPUT tag is used to specify where the XML pages will be put. # If a relative path is entered the value of OUTPUT_DIRECTORY will be # put in front of it. If left blank `xml' will be used as the default path. XML_OUTPUT = xml # The XML_SCHEMA tag can be used to specify an XML schema, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_SCHEMA = # The XML_DTD tag can be used to specify an XML DTD, # which can be used by a validating XML parser to check the # syntax of the XML files. XML_DTD = # If the XML_PROGRAMLISTING tag is set to YES Doxygen will # dump the program listings (including syntax highlighting # and cross-referencing information) to the XML output. Note that # enabling this will significantly increase the size of the XML output. XML_PROGRAMLISTING = YES #--------------------------------------------------------------------------- # configuration options for the AutoGen Definitions output #--------------------------------------------------------------------------- # If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will # generate an AutoGen Definitions (see autogen.sf.net) file # that captures the structure of the code including all # documentation. Note that this feature is still experimental # and incomplete at the moment. GENERATE_AUTOGEN_DEF = NO #--------------------------------------------------------------------------- # configuration options related to the Perl module output #--------------------------------------------------------------------------- # If the GENERATE_PERLMOD tag is set to YES Doxygen will # generate a Perl module file that captures the structure of # the code including all documentation. Note that this # feature is still experimental and incomplete at the # moment. GENERATE_PERLMOD = NO # If the PERLMOD_LATEX tag is set to YES Doxygen will generate # the necessary Makefile rules, Perl scripts and LaTeX code to be able # to generate PDF and DVI output from the Perl module output. PERLMOD_LATEX = NO # If the PERLMOD_PRETTY tag is set to YES the Perl module output will be # nicely formatted so it can be parsed by a human reader. # This is useful # if you want to understand what is going on. # On the other hand, if this # tag is set to NO the size of the Perl module output will be much smaller # and Perl will parse it just the same. PERLMOD_PRETTY = YES # The names of the make variables in the generated doxyrules.make file # are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX. # This is useful so different doxyrules.make files included by the same # Makefile don't overwrite each other's variables. PERLMOD_MAKEVAR_PREFIX = #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- # If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will # evaluate all C-preprocessor directives found in the sources and include # files. ENABLE_PREPROCESSING = YES # If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro # names in the source code. If set to NO (the default) only conditional # compilation will be performed. Macro expansion can be done in a controlled # way by setting EXPAND_ONLY_PREDEF to YES. MACRO_EXPANSION = NO # If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES # then the macro expansion is limited to the macros specified with the # PREDEFINED and EXPAND_AS_DEFINED tags. EXPAND_ONLY_PREDEF = NO # If the SEARCH_INCLUDES tag is set to YES (the default) the includes files # pointed to by INCLUDE_PATH will be searched when a #include is found. SEARCH_INCLUDES = YES # The INCLUDE_PATH tag can be used to specify one or more directories that # contain include files that are not input files but should be processed by # the preprocessor. INCLUDE_PATH = # You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard # patterns (like *.h and *.hpp) to filter out the header-files in the # directories. If left blank, the patterns specified with FILE_PATTERNS will # be used. INCLUDE_FILE_PATTERNS = # The PREDEFINED tag can be used to specify one or more macro names that # are defined before the preprocessor is started (similar to the -D option of # gcc). The argument of the tag is a list of macros of the form: name # or name=definition (no spaces). If the definition and the = are # omitted =1 is assumed. To prevent a macro definition from being # undefined via #undef or recursively expanded use the := operator # instead of the = operator. PREDEFINED = # If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then # this tag can be used to specify a list of macro names that should be expanded. # The macro definition that is found in the sources will be used. # Use the PREDEFINED tag if you want to use a different macro definition that # overrules the definition found in the source code. EXPAND_AS_DEFINED = # If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then # doxygen's preprocessor will remove all references to function-like macros # that are alone on a line, have an all uppercase name, and do not end with a # semicolon, because these will confuse the parser if not removed. SKIP_FUNCTION_MACROS = YES #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- # The TAGFILES option can be used to specify one or more tagfiles. For each # tag file the location of the external documentation should be added. The # format of a tag file without this location is as follows: # # TAGFILES = file1 file2 ... # Adding location for the tag files is done as follows: # # TAGFILES = file1=loc1 "file2 = loc2" ... # where "loc1" and "loc2" can be relative or absolute paths # or URLs. Note that each tag file must have a unique name (where the name does # NOT include the path). If a tag file is not located in the directory in which # doxygen is run, you must also specify the path to the tagfile here. TAGFILES = # When a file name is specified after GENERATE_TAGFILE, doxygen will create # a tag file that is based on the input files it reads. GENERATE_TAGFILE = # If the ALLEXTERNALS tag is set to YES all external classes will be listed # in the class index. If set to NO only the inherited external classes # will be listed. ALLEXTERNALS = NO # If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed # in the modules index. If set to NO, only the current project's groups will # be listed. EXTERNAL_GROUPS = YES # The PERL_PATH should be the absolute path and name of the perl script # interpreter (i.e. the result of `which perl'). PERL_PATH = /usr/bin/perl #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- # If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will # generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base # or super classes. Setting the tag to NO turns the diagrams off. Note that # this option also works with HAVE_DOT disabled, but it is recommended to # install and use dot, since it yields more powerful graphs. CLASS_DIAGRAMS = YES # You can define message sequence charts within doxygen comments using the \msc # command. Doxygen will then run the mscgen tool (see # http://www.mcternan.me.uk/mscgen/) to produce the chart and insert it in the # documentation. The MSCGEN_PATH tag allows you to specify the directory where # the mscgen tool resides. If left empty the tool is assumed to be found in the # default search path. MSCGEN_PATH = # If set to YES, the inheritance and collaboration graphs will hide # inheritance and usage relations if the target is undocumented # or is not a class. HIDE_UNDOC_RELATIONS = YES # If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is # available from the path. This tool is part of Graphviz, a graph visualization # toolkit from AT&T and Lucent Bell Labs. The other options in this section # have no effect if this option is set to NO (the default) HAVE_DOT = NO # The DOT_NUM_THREADS specifies the number of dot invocations doxygen is # allowed to run in parallel. When set to 0 (the default) doxygen will # base this on the number of processors available in the system. You can set it # explicitly to a value larger than 0 to get control over the balance # between CPU load and processing speed. DOT_NUM_THREADS = 0 # By default doxygen will use the Helvetica font for all dot files that # doxygen generates. When you want a differently looking font you can specify # the font name using DOT_FONTNAME. You need to make sure dot is able to find # the font, which can be done by putting it in a standard location or by setting # the DOTFONTPATH environment variable or by setting DOT_FONTPATH to the # directory containing the font. DOT_FONTNAME = Helvetica # The DOT_FONTSIZE tag can be used to set the size of the font of dot graphs. # The default size is 10pt. DOT_FONTSIZE = 10 # By default doxygen will tell dot to use the Helvetica font. # If you specify a different font using DOT_FONTNAME you can use DOT_FONTPATH to # set the path where dot can find it. DOT_FONTPATH = # If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect inheritance relations. Setting this tag to YES will force the # CLASS_DIAGRAMS tag to NO. CLASS_GRAPH = YES # If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen # will generate a graph for each documented class showing the direct and # indirect implementation dependencies (inheritance, containment, and # class references variables) of the class with other documented classes. COLLABORATION_GRAPH = YES # If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen # will generate a graph for groups, showing the direct groups dependencies GROUP_GRAPHS = YES # If the UML_LOOK tag is set to YES doxygen will generate inheritance and # collaboration diagrams in a style similar to the OMG's Unified Modeling # Language. UML_LOOK = NO # If the UML_LOOK tag is enabled, the fields and methods are shown inside # the class node. If there are many fields or methods and many nodes the # graph may become too big to be useful. The UML_LIMIT_NUM_FIELDS # threshold limits the number of items for each type to make the size more # managable. Set this to 0 for no limit. Note that the threshold may be # exceeded by 50% before the limit is enforced. UML_LIMIT_NUM_FIELDS = 10 # If set to YES, the inheritance and collaboration graphs will show the # relations between templates and their instances. TEMPLATE_RELATIONS = NO # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT # tags are set to YES then doxygen will generate a graph for each documented # file showing the direct and indirect include dependencies of the file with # other documented files. INCLUDE_GRAPH = YES # If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and # HAVE_DOT tags are set to YES then doxygen will generate a graph for each # documented header file showing the documented files that directly or # indirectly include this file. INCLUDED_BY_GRAPH = YES # If the CALL_GRAPH and HAVE_DOT options are set to YES then # doxygen will generate a call dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable call graphs # for selected functions only using the \callgraph command. CALL_GRAPH = NO # If the CALLER_GRAPH and HAVE_DOT tags are set to YES then # doxygen will generate a caller dependency graph for every global function # or class method. Note that enabling this option will significantly increase # the time of a run. So in most cases it will be better to enable caller # graphs for selected functions only using the \callergraph command. CALLER_GRAPH = NO # If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen # will generate a graphical hierarchy of all classes instead of a textual one. GRAPHICAL_HIERARCHY = YES # If the DIRECTORY_GRAPH and HAVE_DOT tags are set to YES # then doxygen will show the dependencies a directory has on other directories # in a graphical way. The dependency relations are determined by the #include # relations between the files in the directories. DIRECTORY_GRAPH = YES # The DOT_IMAGE_FORMAT tag can be used to set the image format of the images # generated by dot. Possible values are svg, png, jpg, or gif. # If left blank png will be used. If you choose svg you need to set # HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible in IE 9+ (other browsers do not have this requirement). DOT_IMAGE_FORMAT = png # If DOT_IMAGE_FORMAT is set to svg, then this option can be set to YES to # enable generation of interactive SVG images that allow zooming and panning. # Note that this requires a modern browser other than Internet Explorer. # Tested and working are Firefox, Chrome, Safari, and Opera. For IE 9+ you # need to set HTML_FILE_EXTENSION to xhtml in order to make the SVG files # visible. Older versions of IE do not have SVG support. INTERACTIVE_SVG = NO # The tag DOT_PATH can be used to specify the path where the dot tool can be # found. If left blank, it is assumed the dot tool can be found in the path. DOT_PATH = # The DOTFILE_DIRS tag can be used to specify one or more directories that # contain dot files that are included in the documentation (see the # \dotfile command). DOTFILE_DIRS = # The MSCFILE_DIRS tag can be used to specify one or more directories that # contain msc files that are included in the documentation (see the # \mscfile command). MSCFILE_DIRS = # The DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of # nodes that will be shown in the graph. If the number of nodes in a graph # becomes larger than this value, doxygen will truncate the graph, which is # visualized by representing a node as a red box. Note that doxygen if the # number of direct children of the root node in a graph is already larger than # DOT_GRAPH_MAX_NODES then the graph will not be shown at all. Also note # that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH. DOT_GRAPH_MAX_NODES = 50 # The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the # graphs generated by dot. A depth value of 3 means that only nodes reachable # from the root by following a path via at most 3 edges will be shown. Nodes # that lay further from the root node will be omitted. Note that setting this # option to 1 or 2 may greatly reduce the computation time needed for large # code bases. Also note that the size of a graph can be further restricted by # DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction. MAX_DOT_GRAPH_DEPTH = 0 # Set the DOT_TRANSPARENT tag to YES to generate images with a transparent # background. This is disabled by default, because dot on Windows does not # seem to support this out of the box. Warning: Depending on the platform used, # enabling this option may lead to badly anti-aliased labels on the edges of # a graph (i.e. they become hard to read). DOT_TRANSPARENT = NO # Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output # files in one run (i.e. multiple -o and -T options on the command line). This # makes dot run faster, but since only newer versions of dot (>1.8.10) # support this, this feature is disabled by default. DOT_MULTI_TARGETS = NO # If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will # generate a legend page explaining the meaning of the various boxes and # arrows in the dot generated graphs. GENERATE_LEGEND = YES # If the DOT_CLEANUP tag is set to YES (the default) Doxygen will # remove the intermediate dot files that are used to generate # the various graphs. DOT_CLEANUP = YES diskscan-0.21/progressbar/LICENSE000066400000000000000000000027561456470715000166140ustar00rootroot00000000000000Copyright (c) 2010, Trevor Fountain Copyright (c) 2014, Johannes Buchner All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * 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. * Neither the name of software 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 COPYRIGHT HOLDERS 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 COPYRIGHT HOLDER 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. diskscan-0.21/progressbar/Makefile000066400000000000000000000017211456470715000172360ustar00rootroot00000000000000EXECUTABLE = demo SHARED_LIB = libprogressbar.so STATIC_LIB = libprogressbar.a SRC=lib INCLUDE=include TEST=test CFLAGS += -std=c99 -I$(INCLUDE) -Wimplicit-function-declaration -Wall -Wextra -pedantic CFLAGS_DEBUG = -g -O0 LDLIBS = -lncurses all: $(EXECUTABLE) $(SHARED_LIB) $(STATIC_LIB) debug: CFLAGS += $(CFLAGS_DEBUG) debug: $(EXECUTABLE) doc: include/progressbar.h include/statusbar.h mkdir -p doc doxygen $(EXECUTABLE): $(EXECUTABLE).o progressbar.o statusbar.o libprogressbar.so: $(INCLUDE)/progressbar.h $(SRC)/progressbar.c $(CC) -fPIC -shared -o $@ -c $(CFLAGS) $(CPPFLAGS) $(SRC)/progressbar.c libprogressbar.a: libprogressbar.a(progressbar.o) %.o: $(SRC)/%.c $(INCLUDE)/%.h $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o $@ demo.o: CFLAGS += -std=gnu99 # Demo uses usleep which requires POSIX or BSD source demo.o: $(TEST)/demo.c $(CC) -c $(CFLAGS) $(CPPFLAGS) $< -o demo.o .PHONY: clean clean: rm -f *.o $(EXECUTABLE) $(SHARED_LIB) $(STATIC_LIB) rm -rf doc diskscan-0.21/progressbar/README.mdown000066400000000000000000000033101456470715000175750ustar00rootroot00000000000000## What is this thing? progressbar is a C-class (it's a convention, dammit) for displaying attractive progress bars on the command line. It's heavily influenced by the ruby ProgressBar gem, whose api and behaviour it imitates. ## Ok, what the hell is a C-class, and how do I use one? progressbar is implemented in pure C99, but using a vaguely object-oriented convention. Example usage: progressbar *progress = progressbar_new("Loading",100); for(int i=0; i < 100; i++) { // Do some stuff progressbar_inc(progress); } progressbar_finish(progress); Example output (from `progressbar_demo.c`): ![demo output](example_output/demo.png) Additional examples can be found in `test/progressbar_demo.c` ## Why did you do this? One of the things I miss most when I'm writing C instead of Ruby is the how ridiculously easy it is to write user-friendly, informative CLI apps in Ruby. A big part of that, at least for me, is the ProgressBar gem -- and since most of the time when I'm writing C I'm doing so because I need a tool to handle some long-running, processor-intensive task, I'd really like to have a way of seeing at a glance how much time is remaining and how far along we've gotten. Enter progressbar! ## Can I use it? Of course, if you're so inclined. progressbar is licensed under a simplified BSD license, so feel free to take it and run with it. Details can be found in the `LICENSE` file. ## Why doesn't it compile? If progressbar fails to build because `termcap.h` isn't found, you're probably missing the ncurses dev libraries. gcc -c -std=c99 -Iinclude lib/progressbar.c lib/progressbar.c:13:45: fatal error: termcap.h: No such file or directory compilation terminated. diskscan-0.21/progressbar/example_output/000077500000000000000000000000001456470715000206505ustar00rootroot00000000000000diskscan-0.21/progressbar/example_output/demo.png000066400000000000000000001551531456470715000223140ustar00rootroot00000000000000PNG  IHDRq q iCCPICC ProfileHPTWϽm;, 7UTRŎ(""PcAD.,1&sh*Z6G;,tz':]C{9W #a\0A6&)`Z01ØIcU&Xgl06 =mvay'Yg !~ @P"< B5p0IX" UD?b,qDN##H$S7)TB:GI'}$ vPr* E~H~GP)֔J rʧo5?_߆&1e;N2QyA```-i!PPikBTUjGeQRש4,MBisB†e—yt]BGDDlD"E4 ,JZF6~s;,&D-.-.~RM\%+q^$,.#Md伔TqkRtikX"32TK"+2/eemdeKd{d$R*U( Q E s2)JJǔzU))Od4RTTTTajqj'au#h2F AM&GJsTeը5Mvn~sXW竮nnc=!=W,N,2G]o 5 # O>0y36blb5n21Q4 3)7e^|MS.Ӌ͌RΛneg`>Ne]uLJ e)KӪ깵uuM׶\E;3v]({'\~!RlF9'#mN]g7Σ.R.,z9W=nd7_R\Nzm/$^e/||R}76.=WO X , ,  PМБ*36$)~ӥ/a>3=Up9UuDQLEdaTETa4ۂ}=m]=cS&9"v136n9>09qzHo2K2K:4u$CShȟg_jwiiei/dfp2o=u*1mmm>fGNhg] wMv]'n/YYY̖ޝ=w9|9ܜ}*?`pt>o}<=94rp]`af#EEEn>zذX1^{Iq㇎...-k.,?Px"IMRyNŜzPTZ\U|{:?׈||zM$ ƙ3gڟmojl7RϽ1Ǒn/0.4Sy %j:knp4lYڋr. _*L}yJĮ٫ݛ_ vǻ7o\r[f:n3n1g/-wMt+7^˃+ER)U̼m@= pHYs%%IR$(iTXtXML:com.adobe.xmp 2 5 144 1 144 694 1 113 2015:08:29 19:08:98 Pixelmator 3.3.2 fb@IDATx}xT;L2=B !&U)bA*MT"@D:{}&L&I&~TNS?s@a+DU}ω*TP9r@ʁ5mV*e.& hѯ*&QJhW-l+_#{+ࠅ^)Dï8@稭[T_*TP9r@@=ܰa[e2#-oޞ?%cx^\zu'4r;XH=z;g5U) Wp*::j{r*A*TP9r7 =:<6o)|@&ݹm |էh,Ќ CuBy c/ Za'O6xy߯/y K>}n1u1CƏÙm6OMG*TP9rnȰ4Vuј3e ^_:ʯkqXJ䗙?p #6.1 }tCQN_ļlX1[\@>1_WQ,Z<"bmP%r@*TP9rhаYd|Ƭdj/xaˋzl$? a!A8ph'X.?.2t@= Vѳ`4 㵈+,GY~N塪,{ ^.pD搚R<_*TP9r@*4j}/A!OFLz#;㙗DIOwf0TP c{UD',it0ӑ L)W?"- ^GGg-?k2G ;E06ꎁhbĕ WMd*TP9r@dւVE/&O}-bY98v)9lu LQܹcăHJIAzV tUex聾+yLg=O^VVJc. vw^=;"| %9;[[ 4 8ʊ4pt(7ؚ*TP9r!\u=Z8;P^VNPϿL}jO7cG ޝ/^w؎~nFVa2&tm)'ҭZחmYz4]\ps!/'Wy\:z4@X^8't#ecxqqm`ђ^T>yO</{܀ 61>4QdT~NV:]Iw#s`CfϞskXBdKR;H' ɒ׿.zb?DW8ԯnǢ m /Z5~p}eN}e~4, 7 W1lCOo %/ox!.?n5qNٱ~;F֯Fph{ϓX;5FgaH>=1<źX=1ok=]-xQ¤VkgjymH|n,^`˯(  &⑧ǥ3gz>xֽϣXl4X~~]:$8`E0⸶34xrsjz38Y?섵Gcї0nafp%twKia nfw^n2$\dä󄗫Ά^c&J'vD_ G7 +'ĄfqzALG==%leCz~D^u0!Xu&&NJQVRތ0wÿpH4?"۱IB9_Ma ]p`0sz)ꚢCc^FƝDs 'Ǟ@k+maCO> pDبnpFT/W=|Vt\rNǹ&FFfLkNhdE.]> qFeSkA2֦T\i4j pBCBgKgHfj"ϣexx:IgzU9N]=ளpE 7-gJ5,Ϡ#WѩM8Tpj: g\tCF%+:锂\NAvn l@v@[^n*ĉll^ r7ӵ,I|jז. 0RJлm,' g*лM'd\ }ڄ)3۱) s{\i$Z(>3,{0؝Jg : G>_63&oJ:G_eŗ,Ʈ_7ᛟł2](v FHNa[p'0PYeCO_N&+- TQRZd0(G>v/D8a0ȝxvRJY6dyYq(wxzŬ{nf, NWC ,J}4= mefrv[25EfZ,4qW5T%==5 DLc g$\p wIfHcMx4xRb*eKHOLW@* O+YBr|hxZ~J4ckQ+Otbr@ǥ#&&4mN4LKND\LB1?!*waD\jc3etSҐLJY*$hVoe9b3Au\T0 6#q/҅yWGˊ}I^Qbd+W( d\RZJ8#-7::JY.Bjq6e"T+6td9N"4K ҐULZYӋSm#'i5i %#NҬ9(qA=5O2C1k0QELD]'&2(Zb".& *ń/1QK 7b»& O;H{6X `+1QݝZL+VX`".&@L$7ƄĊEJ'*KM$`ENj0?„Hȭ KsDLdH.4"PN$x5rrhDT e HLHzb•𶋉D;(L1;zZRGO44g".]&.zBO k,K=n',D40!!+ |lʳ.*mFإd@β&VT"9Sˇ~?/@v)$yaލxίKQzh )Y?`#- Qt |l$n&쿐&@2L\ #QE16D E\*+otoQ`z 5P͝x|2 @[PlZr`vDirIЩ:X$=%ƈBVSQG]Zu3Ԣ«LW|s&n%ph\87ę87UҀ;W٦Ef-pr2J/.fr&NY4tF4j\[]^bU"$+Swt- R8VYx;e1`U΄b2*@x4^XRomur]̀v +dw >*Ю gKzE>ؾǶ,)خ3-KPATjSRWqm!֓uTr]V\I7$ZL=֐ z=BY&tZcKϬ=]#ɭ;8 NNO(2tE.ڪI)M6EykXHRTgVxk zN#*ѵyz'73 My҉0Q@Lt+I&&jSD,1ah hc©qgwfգDDgb;{kd b"&Z.NbłĄǶ!L3`"p b͑t| LTTcJ)pIFv]nDG+|*J%&c0 ^/&ʉ ALt\b-&J2=׋Rba"7Ex_}L$Z{0͹Qgez"_\2IFb".&ʩ'Z{l.i?+-}Lib.ZRm0AJl=LPxtFO[=i!0Ѽ3=|_`!LsEѤUYb4r O; &aB:z+RO` DD+R'WWOTreN@I*ܜ,q uU6=Û!NHbBI/ n?Yy62#;Æށ+7ӳO7igц Zsa<5f|Ǩ i;a+$ǤaM1PYT?{`ZVus+|bd0bXhܥ?Fh/-өiQiO4itCOḽSc,\:9`sqS87n+_ Oy*CWǢϔg9h֢ .$c jor~Ne.8`埢ӄ*)E%cK{HnyI v|[`?Pce<ƛ=Z' P2c; x3^!v| _EwY7gd_ o@Oʍ鉿#z~C2~1Q=7kR~%:kaYliC➧_'M36vՒGt6XQbhЯ+,|-K^X=o00L'L6BKp6=:sjMkn<2=<Euߠ(*(vn zYi`3ðѷ? z/$܀\x q3%'k->aNCE"TaYpY7W'w_{esp?'+/ڌ~.볧!7;:W>Imlu-gɫ}H,\ ȦmO\Zđݻp11~L%?8giኂIW;`K9w_qnV7UP9r@ (C "-Zb-K~ '駳M2T{"H6,N:҆+WjbpUBʺ䏽l^ӲᖸyjJYNMSu9N=V[Ժx2[]gyPu_s$1Snd䄪iBy:lyJ,RUP9r@;pddu\hu,$[ NKk#WҤ!}ܼɺYglK ϪN1.۫Gc1Ui{*TP9r@UBvXƴr ҍ-78=<6Ά9;,|k4{e {w,u] _W'g2?}YȺy6e}'kWkY5&5-Uru:y'&I%R9r@ʁ8,S_Ox\ۊ:V)u}H>j%C#gknm6Do+5xe_,:Q 2;9ZM6mtI6SzUpXusz=\\\ꪜA"35Y8dJFT{k1sO=ܿd΅Bd "\lĔf\%t8:yWߛ46 SiJ}h)LZޛS2ض]^q7,8'w}ATϺYEXi96dȸ*aXA4 测qoȆrգ}K0_|&P?Z[*TP9rC|QOᣇ1hh$p"o7ĝ|EFS Wi 0m8W?#[0dD$Emc֕ JT.VŽz0@-,t2o=ݩ Gl>w~^O.@K Y% #]Û?s ]$RJ¬gM lO֯GN!0QbSs'^<*_œ+iS{ޕ]$aK-ņ5o`(-Cq2ӝi\ϋ惪{I8=M%Pl 妣1?Li sY9yٖ|v>b+\Tp ~0xN LeZ;iy>4Sߡ xZy9]r'3[1vaHYVv$Vbwmݯk,ۜ\<y!V⤑,ަYyFMbˁF}A. Ov) /eD|@ gX]Q'R~*DFYF3FBmW.ڀ~!ɯGT//VSɶd>>+_.xRƝ/7XI0Ȕ\P3Ӌ":mti6gxyi[:oUP9r@04ԧ {7TN=cs'{X6131#BF.!]0֛&Ha|yZֻ{*1篪۴ ?ǣ`Wi`W4Olysy@E`F<]Ee4y4>-+; 7l4M1mp6;G+WO!NiikEX OIO۾X4XK_mD\X0zsg1E8z6y],wd"11A$%ƈ' zoEbJHIN@@1v|_u"2rđ߈6Me?iωS"ETT(./o/cE:3\=c.'q3..]W\;5>m{DB"~-!;"6ř 3׮sĮVV:Y>[lxwxu~p&<ė0Iɫ oųsfM^bcWbןgEVfI#h{.'._"vNxPgl+ .^DUpBK縸mDqRHIICz.Ħ;Ū&NJSA@pw_El\rG"V˯噘,`U[?R NЋ]~? bcbzV,{Btid 48uhDG*|hSFr5?%1eMuMYwsƑ , 2]v|~}OĞ*{I@;QRǘ篧.Z6aEg\/PjsX9[b6]ӹw~_-ҧ% <@D]:*~H(:i!>}Ifptr_n?MoەbKbQ.ytؿeظg">XǴSeϋb/NCQJ?xN/r(x"vM#CZu?fůW /׾s-YˋLP<2>T~9PW^9Wӯ˯ً1y[ Qa2AXDe^Xѫ8ۘ}$>\?|6`ݪe8իx8|*̟qZ^grX![:K'"񖻰3-/ǍXu^6?t[;%K얻1m}xEА)xg5#v'٠UOso?_员\k(7ghÈ_~ wq̳Xtͻ(<%>V+Ƹ/`=(K7W &XT^\B yz1y \G87%/4qAeLCU\HWQ)NA@/ =t=mpVf7S2xy쥥|qUϚ 2xjz|B·dMyIO#=0z285?G.WP,7hHI@@&)s_;BҳѸqé,;S L[+ˑɣǃResR$AjvI/!!AXUb#t.T!% M7b)ʵ8Њ<VZʓ^*4iOR-XLF*%?YCQ6$Їϼz\Wf!Mm &*;0<ɺ ;PDxJ1o.Ą?ĄV ĄL^<4FX Ucj?Ą_aB+sVի(\!O|_z~7ݍ;<<%# |Ǟ^vC. " ]iқS#fAa1AZnliS;qÕ3Z5mІWjmt 8~,[,~7Ǝ N7ǥ -Ĕ&ܴn2`^ #Wbm;p >vArILDA<1F7v"mcb}1k]O=y"N1|[u6ϟGf;f}7}՟}%gFކ>=6x.tP ٕhUcP@u>@ l1yUiG1ða!^ AϮ FߺC|e4;3& 7w[ԨRe{ޘ0>Z V~=?LچJ_~vmD_9oݑHvn\.ex_`ϰh& 5 ܁O.xerww&'vd8HCɇPf08;Bx/\m_qnYTa># ^+KcwFa*'f]ElI-WPns/#nI7?Y>;,>W9JX/s 'E.{ҙ;- mc/+)g@zRiTx?Ca-Us &hjC>+C?2)*ۢO/drI╨pelV/| <: ȽVKW7ZƉ]r3;#/GA՘p95?=W8{< * Aq4oZ݁ꙫ֪9>HDxx7n.ko .,;ASYQغ#HW.9q2DL:Gtc1ӥ2ɸthϸ2+:<혏^US ަ Z$ѣM[K,NbW]n-Jrl2)t * Y`xOu=R3YGmJrp%_dRfUalZ%&bv0OLt3ѳ+O-A(9?ᙩQm߃OYS6v1+ >/{ LjaK?py0c~VJ~v|blƒ<\NQdx#_կpJG ٱgXbA,_])3=ѨDs!d1@yޭ=AK\gLk8ς@IDATwvۏGǏJcAs{~ę|)ӃYsRy+tB9J; Dw7w;X:(#ZpTq=tz ,G+6 _wg06/oe<ȣ8s&=V^x(rFH4HΫYAK7eFTxFXΛm W*+q$3P]zP(B48nD4fePvd0c{򏎎닂P;Ѥ1ƼZ5x.iS^XVy3U>kS9.\Q2չYu19^ؑ򦿘br iᡭ͎a4mv*Nk=5t2YҋȦՓxf#k1`%QatQ :}! .P(iKz'zk&K%n`XhDЫ*`''N4`(=z[$fq'Г\R#R&3IeNJ͆t;T˥VQ'qKTʦURrF!$4IY%pg2ˊ{=I9GZX膢 nfa<=4$VUkzYA*5p#-t)%H)4锵ल^t+\b"t'&rjdYb%/#`|LţXb&H/s;*:+ eVc&҉ Dv}L,93KC-&ㄹN>$CNyĄ5V$&D4 KQ6J kqLYu0OLLɛY0JLXa0! +h(KIIS3Z~("&茠" & \H(\b~}T(zZ5~I7եVr/Myva|`n5MCJ7$_T.6xyy?i<وW?،?q!c8}w9[ߢ(< 3}>&OJq2:f@ |Y/AK/̭*./kEt~%Cd٨?QhrEKrlq MhKwը?P4w-/?lE7 2KSQ~ɗ]DД %YiiE\–-?@ҫ';/zrٝb@ؽ >gA7qݝK|5Äb[0qhW_ Y6gb<6? bO",m~ނ"lM}q=zͅ//nQ+Ƹ,Y̝R-?Ry͘E54] l8Ԗ&:Y^r_Q#t&0X)_KEEi&l\>Y*/-DI,oO#鬿-I/ß*S͖.'6NNC]i ezLTrBRޚn_n!=NY)f=\^-*-%ݪ,QIOJQI ItOЭƤGOJQ)סWJzI ]>C h]I*|YTiWpC pɳʦ򡲢uR:e]nv-2nE7˸^˷/oK7IXk]䛡>&ɾ,/e_zXY 0Q.13bEqCVׂ ce"Cp%׍ s=RbC ~itSb+}p5KL4 +QxA}c(S0a-fL606`Ė ]bry#uhu.;&Cr#C̎s~% c!,]^Y?1DrQ ߢ!LW oƦ+R=iQcܥ < lwPTqC'VrmtBRcOeD7|;$+z1 ;7[wq6-YI1/Ŧc=Za0CA뭄5n:i a%xi a׼mdwR5"]{8txX埊V,On#-ܺ.&>NHI"1!V:%hzʬ"&LOJKW k΋GMiټ?Qg㻷έӉG+ӹA,Q^v<q)&A蓕*^t6OtlX(~ݼFu dp>1ovq<2^f_6!~s@̽s-T::໽b!J977G=*cŗ-~;pX<:">9UcgڷM nL2 ߸"͞ fE9VsxK>h]iCʼn Q"edw> qYrrrnIX/bIJV}F?'sT tYZZdĘ⃕ow[y-/7c$yGDDy>Zv$yLLZ6[R3pжE^<"#;[D<(7uwєv7v]·6(u.B(l#֋_7-N\2Lw^NJ?N%.F'$[Xlpf5~/wWE#bxJmdêor̓~%slS'ٕLR_{ܤup}F'~<- ψmS<뷉 A9bw w2)gD[S|yX,>ܼWd}RbOEFzBIHq~1bp?G߉Gf(lxKxwe4-}wpf^8G$'Db…ͤ_x I⧯>ؠ^yL# [2J.ّ̳ .gY4,z)rv O2qDK5qHʣϐz01޶ES$"5;_+ %c11y\Sȯ`b`.! vcL_42ej&~#|YHcd#x2,h@drYg[;NX 4C07D_Azb鉳,cfͿ-cmҢ%q1teg!hɍvFza䩼_N'HY~=doP14SAyN|"<-9%듞A& %ؔ^po\V,ϰiA+%NLh5}χRJH a_YH8ÓcOyؿ-ۿ5"/ǡ$|?1|XKʪ̫˙`j=W;9ѨQL\Z+ [5BfJ"x؃ [T y:展c @S*tŕ_*TP9Rg3:g]ZGY?W inWtU*鱗 _Lɸڠ&V32zEi1ـsG!1ַh[yW.U(R0B靡ecQ,zU}Dv =찁18ܳWGǩ'QFӶC'r55# _Ic/-C WD1Rf]k͵ [ybTXq:@cN9.taG*Z>%LAi9;>h)Ah0chIʣ۔F {eYYZ=r4Yn篝rrG#[橥$ۨκeh[k_)?6ӬNcDceke]ge<$ZG3` /6s7~\E<;c eɦn#3Ү_ʂ LZRn丬)XWu6㲾Dw P/*TF.7C-Zekc:*@ {/қ""" RTTO!6@l4A w Ҥ{O;wdOÏdsvܹ7̙3WU:J*_Q8-CNeڞg1WcXqHE= aZ/X-\l*/Ө*/0͛2gNF?vW4h8qf.߀vjq@9EaLzXx5Z,*k8q@ƁYXQlŧ~b;./jx(ռ ENStm6p?m}zq@$fta#Wقt&C\ W9l9K#],R哇̪hT2g[a[ . :A314glQ: 7'vb fIR,dh| {iͬLG>>< {r ,R-0Uxy?܅ѣZvF}`ۢ1mXg2XM?/DG A$G'` U,Ѷ?ZO>I;cT݋GNi;hҸĜBbv2&'">9M Ck$ ;)1x*4y> ?IFeF=ec WEx3ޜ=y4mn=NR6G%~V4h8q@EZE1Qa/؊ۧT g>i(lVElJ6-ŕLwcd>AZTKж[9M7@|vztl3a :vk;>ljlzxju du‘-l fFz mx~[ǟiOW~E7F;ٯ+ozs`&G!2, ~[bŊ/&&wG8brb-QsKdKcO/>_"~bpebM1a82}5p=1m<}>փ |j08dVi -z-cNAj4:"<3)6>u7~zF==! ü2Ȥ}OCSMt7z9"1. [-x8b`Qͫ F 7S:G:s+>D .~uytѤ13L}U(<)CdT8B-#[Q & <* Bᢏ,a"&FMҝM\܄cP'86tLR݈MB:!gp(SJcZai kN/Bsz׫SG}FC;e'`о }{uj>鹩H+D 3zIN "Ӌ 8UG8G 儓9aryw1PNQNԣi'&B)'t&~i^1O9QLN0k֬Etb[)ǀiW癎7- LL5!}ā)@ẂÇ[O O]Dg1mAY>.?w9=qSr]w[XϷaPbT/}/T4z$ѧM#daoq‡6]GVLFÑN۹tmB1'1O{kهP΁)E SfY⥇Ǚ4_ܾ.^zlmkxI"loZ+D^jЫiN']G\'Z_~ =%6hLoJOC} {җ:F3z\ Qύt=~l]0\CPńnHo(ac}DDx֫x5#, >PD3{Sm *†c|-5kKw3{[|݇Ms8qH/[K[}Qn x؛91ܸ-AXtJ|_AHp1A67"49a4ahR* tjબifp0k$qhѠI'LLxD&%OK01)7R+ =^1hՠaĩ$?h]T\ 5 _Y=e7C.2rav,~N8-u4+h]/،\}1 [E <2SVf)pC|3L!MW6/$&U/rj+昈'&`hb&" ̼dzLx 1cߙU BwbB& K~ĄLԬގ&XLiʘ6&" EWV7DSbhޠi"PD1oN"WJ1V8bL$M1,9I*$2&∉bbs'&ƾ`""TD41Ѫ&2('b=('ƾ5LȰ%&h01`KX_dW.Ąb<#&j cͿ  #W)' ׊E`B{_ۍ Ob%lw )˨ zدo"'h]ۀj)rN mN;G4ʒpa3hVk`+ kp:zo`߳1ju[;{}%dAUz݇bvX:k*bkXO8 Sb<W;౸C;Wл9yh3l3Af`-C/!rQSжK+<(t9J3&)h^ _ƹ{KXh)domJ37xRh'!%3ieh}ZY[[&MBHG0jQ;Ksf{R$dD8ȡ"0[Aen^Ha XŤyoIVLL~(Nμy*ݶOHg;3z1ID<GgB_&2Xl SJ^=E-~Ҝ_PF>]Է0l&tIQxN!, 8}tZlUC# Oa1TNI_ w}Z EW)MX`O.Ӓw6>)_]wC.WY7)M}b[z_/m?%ۉZX_Se26J_VmտKFVƬ/eWl ]-)~9nv|6-aB]( *&V0! yO;2ebϣbj[ÄCEL"&x_SLp|a و 駡6\XfkBTqw71K:ͽ1ş:iv*c}@(/#䧌[B^0Q>m*L F}k%E7+c2&bBk0d%L 'aBŴ!1ÜQNo S 'n 2,'`wo.'t*1Δ)0Xqs,'H[0alLNc< V8`!cPƹ&8-cp_݉2*&m<*'X1:[ {Vk3$PnhBm#|'>~LEcT8:WWu oEq'FO.G_G!''f 9 zy~~cjzv}&y ^m "K_a- 5T$t8ʲ#yOaY$n^}F{S{kW+SęӣFy;bABeŖ#Lbk}Bgvwg`0QP WʘPpc=dC"N] 3 ަ;{4t\ |SLP~\Hw5"'& ('rU(]쨷RvQҎnM݃)ΨC[ b7Hl_Ũ)ϠOwxee$P8zlKpytØM0wZ <g^ZFwa4dbۓACX`ABYS!>,F5 S/o{}t:o?:%(⶚oh{|b0 Sa񊭪rEWc┗1¶[3|eYQ* T_/ 4q` եoNuV[cOq6ZF+9PݷnX]_lU۲6ѭ=mu債&ӿRݷkX]_-Z֞px8/:MbtS*v4ĜāSyϔpA;/ /7;Ǖ,ZOB W7* |k_ϸD.wpxnnK0eYXiZ]2A_ǐo[౗?`c9FsoِHfރgC~r:lwdZ9\K_OG~p0ėD؃zIzqlw\t " ʦZ,l(5OM(i5y†*b娤:i%%: 1)1q44^[^ P(2F C+4h8q@Ɓt@o֎AhjV-[&E\ We0ܗɋ2|sSDWpL۬Y!v7YuTF[4h8Os@G c祿3P=݉J5 /F?4 N&j}*wvfzC(}tO`To>T-Ѧw`uϪOovӛ}W4W؉~Q4h8q@>n{$ 󪝷Vj#:d+)ի]4h8q@n#nP9-Ս54h8q@7hY%">0b_N(L,=x+]\RÓ1ʏ2٭TUUQF|CUpߖJgldX'ßmUS-..Efm1dP83͡>%%t61߇V4h8q@9 vΞhӲ9-OG\ '`{3"u'' ă?w4 Qy[_1W5u+QFaᐏ]7Bx<ɧ_޷"] o(2m&HHmƽ#06y<T- ڴ#F L 9äKTJ+Gҍh[<<&73l:V~.r6 ~qsƋ J0,WBx<vw^xO?>1YcWp P4y9`HZ.mkE4h8āRY-O{w(QX4k&;wuaL[8 quEi3`ea_0qtƟ6D2XroZd^ͱv64*@" Qb~hѶ727X1TmD@Y23!w}dyS<şн*ܠ6h3[7t/󮍼?Qq0ILtG-;xao`Էv\*7{U,^vcɛH<| B|=`틶Lex5Qn,GŝLOg{d1#7N>ҹ=cdH`n^ڱ# 핎M1EsQ0Db8vM.ǭnr4h8qOs@8}V[sݔH`4n~>k2|{vȦz4ޣ]Se;_R# :>M{}p-à-qq!(0- [v`vqXSn`Ϡ{C6t_3Lǻ=.Jt6k}&Ȉ#0ɗ;]wE0eHק2.zyض)<1n8^u[]fZ 5Lar/e z+}S[Oc[dx6ꊵ_,K9Gft17pjOfҪ(nChS8jv9D;cpg!,[R5ؾ퐚/Rk8q@v{ ѻ~'[PpfRLNT JG&uLZ0Kg6, t9[zq#⭇R߱ ‚;Яv67C_|[ЮG{qa݋QMڵÞpxúͻ8gFb̃Ѽm۾1X~ǁ}GGw0y>ˠhs토8g6ڽ>KP 4s܅t_FzR<}'qb/t5+Dgİa\73uZ=ӄ"Tjl]Wז\ 5Aۮuw}~fZ”$&$rP\O_kݣ{MKO \"`GЬqlf\6`cy 8t FA鸹FoҌQ4h8oqC§@|w0V|7a+9tUU߈1`>*8q?وAvD5cTLВ']g >l˿GP)y3uXv#NׂaOk68W/&g_L{7Dmӻ"|0Wzp\f |`=U>k,<8gÏ;l+1<6X~vh>|3g/@f]L~bg،H*(Fѡ'5}zvC_C3Oߗdvk<&MЏ+!90Y=ƾ۶bC/_ /'ozOx;};YĄŊmИ?l޼gR3pz:l;+,u;ܣ&_W&bGϠc.x{j J2]-sYߎeT.rRJR;7W ˩XW!Wͨb+wzӶT^j3nhK|=V.3^3KW۷@21aIaBcG0Ƹ̽&9V,UL}^]Dz1^]zQ_lq7bBܽxU4<?=/ .-PW;[OsABZ^+uZw p jmCQVg1W[bq[,cV،l<3_}QU*щ7~c/ƙ/FL3ꐝncm0YHSPLsǸ1힦x}ld\PCl|j E8rh&Y)ށxϚo,l@ᵧF/\ط?OkczTjyo*YEk9d~md'b>3WvTd:ͧ6l_dB^Kx89:ٕ)rrr˶("3JPLa(.vO ٳ)ZvMZy}kǫE/۳ ݟi=H`8Z {z@ZtBU.|Y"v0ݜVoҟZuB zuLoZT׭WO1z &i+)q1 Ye^PcԥcBU\ _O6+&D|&P/?C~J7ڹ^h]B ݞ,PepptBHH;%uCjW;9NZU.nBwq@ڕpDZ(P5 Ez@7j/cUQ@_j2 Kgi*&c\y[bA7G0f.D_ +=&+(3#Ա_zzUL誇 fp r3LԻ&*aE0RmLTŊeL V*a[1^ ˘LVń?儯9a?&- 7W rN]XD8WD~T2Zu-ɉbǨHh@ r , ]9&+o0QU~PNTANT„L8rB~T'tnog[=Sϣ"g}aO?#7uV]Ψ|YEgv=P{>e)ՔwHRvg+>zC(?7iϾ(^wekӔGoQv~/sJP 7fx}}:( S>*8(.u_TNA0Fxrlj^OQ+?vF5W~3Fa8J:mS5";@IDAT߮E+?_^~GtXkՇ}iFz+1I)'?nF:A%>9Ey_np<%!%Ey P#()ʬcw ?]I"}L6/+)I1z6ʘ =Q:}܌eݽtn(_GzАt;+[W?VRc:픧f/QRښ,W•;0;(3?\$]SobBwTf-^$^VzoBwR|u^޴ E`N%.ҩA-m7;Eg,\}6nc,ۼ_ҢqlwW;)a)MF QxRwSV}T~;+P.أxn6[3Zz:Ǿ`{bԁJk&}C+ʱ}k0H9(veLl\4Qʞ0A9}#Vٽ#Ņcƀ:*"╭_5D;TL_&\MRV-0DNzL|fhc0R1']>_zw>b&aψJ"x*&^6 ɩʓc2ULR11itG^˱ڭĴW>$=VOXIIVϽ4i P W>wRhbBwV]ʂ5+17N*BX_M?*W*-kbKrJ؅*&+zL*IiPóS.ܫQ-O*Mfp U߷V` _W|c"'|)G.+/'&z9J9v%Jٻin[1C+oWR4`"Q,1yf׼r1:m3L4lO^hqrr/[u[X3fXi>%rb,sLt^lwNP9{asLS0:eljdiч>𴊉0^S1بcJML$*ӻ.x~wv7ENL;eE*&FVij~F ʤMo,co*g&Ҕ'([vwT F2-VEV>JtF*(-TFNB Jر5J G::{ ǔ#vM+4V>vRQQ~JCȕr]7[ӐG2o/){[)(QEJ췃“SagOSzxZ/-Q>]A+c5W>RXV7sK*ã1߭,}JНʴ7R[{JqY3>\+wO=Wx29N>=]]ehCbd)' %aQW+%Yz-\Yp!],z'u*]߈,J )4Ћ Jzn2 S2y:<_S_`/k/6 XusS[B4>;"xO~nJMD |*=Vs>=ϔ&tUAnv>s3H7;';)B1+c;ȧ[KE1ӑ*!=]zq[ )()w\ iBOӻz*ɩ nd¼Bc;dBTv9LfnS4#YI_Dwrq#adgDޤ|w w\BzJ/.1ax_DLtSI;*&XLg[(T"zؗ11%X 11!<4,qMr.Ǽ V99n畏\#UYdH;0D:~*>Lke+7DĊ3嘠|P92+cLŊЋ0QJ~M9]8,\ؗ1T}=U~>rG:e|ȨUq}!JQ_^-` JXQl楪c_-MǸa_1$e2^X9)ł+ rBGDN87r9S+F9a LA&RX1 M0_MLr^_i =]Aeb31mD9&T U 1Y2D=]EVD^qdRL0"R.?l30o4|v;erjXjMO5Q!u먇<=u;!lN[vmp9Z!jL {gɼ/ryVÎ~ۻY?޶lt,}cV&6E9{+rGxa3W 䟌Ӎj㙉/s{ t6DEǝ(dԬ};6e^J7J Wtm\ҹ`JBqv D.oTB! A2Uzf: I4R:{"tn=秧ʴlI^lӧԖ[IޤQ0}襥vtqG뗚շc;neetqE&뗙SV@3S2A;'鎤;҇(CWF9˝ xس~&nC'}OW[d8/J%LGȤ@1;.ac}q'w8tm!oEqʦiS gb;1Q7c"` W>Rb"V zXDŽCRmLde4X!M0NJ 1^*V\I$VLƾM1A8U0@e$„ȉ|ʉ`[1((' tk3z92UGNXEaY\Tȏ oʉˉ v~&,A/*r[[lDC}UyT;-^a9U4h8q@.Tzq@4h8q+ۘ%fV*>06ye?jׯ_b`nW{Yhh8q@@58PBL^Dz໨ނnkZ~4PV[aVО_fm (Z8q@VZ7ߚпxR~ v}zش91UK:f7UTULk54h8p;9P7M`n_~CgLvK7k&Ci:V/[WвcL?E)Xrc9S݇4'+щhغ9FXv=%kڽ9Pe(oj30yXl^|տ)IV1I~Ukߵhqb5eT}wKݷg+}:, M2Q Mfw|*>;,URD*,d~ ц}T_1hSpU@buߣ|W|@-<<ဝږI;4h8p9 }vņ;0k+4l96G`UH |.emcмZwmLS: m`8{Ŷ-Ѻ_y Cغm=:3EAm x׽c1u@8㑙bIXUՊlԩ3+%%  PZ(sR gl H@tֹo]K⏨HLc-oӵ'zu.}3ouھ!--ꖑ#G] w8oXsb(>}j{2]lJ^v4TKexy ; <1e,rm/ -^U"c( ѣV*zu<>(Ih>h<:'WHtkIGBxf s8;#,*9ƇKZ;z0܋"Ob!--nCgcV~l*bjSkWh{12"%+A^^_Q6rWcC/xbދx1Hg@m=_ uA|?.}쇇7lScخZ8ô-Ȁ)<bft|F(7j3X~pXi-mD^#~U\fk8p9 CS ~܌d>#ѰM 08܈hݬ':yu\3 [8u6t#MڵTwm miMf,Mq8i(fyt b}}ہH(c#C)8pSK'Ug~^H#ztjUΣgǮhܼ3fz|:w]l> ˏf`=z'7 7~=}Fe9ޅ 7yh<@,~1Q$”a[XGcߘu0>\sxbx5h[Ww~8ޘ?{V]zj3o{~#/WWSľS˜*[6oƦ|C;cïv[{6) g;sєZ4h4?r諶a9x⅏{smWP0;2Ca>7oq2/\++o,@эx^CGw`a;vv:d_żEˑ.u];G~#DYCc1\qIxh 9ܕtՇ꼭WC&#x~u.d܏07ה_J?Y6i p3.C⒲c8z?xNj`~3ڪ=B Cx( /YJk#JrҙjQu>๯aR~Kn2ۨG0^ٜ.b+E,6]w1æSK螗̴޸瀑w!/LWРQĬiyٙ,С (:,x07+6'MyF)![}v":%AH`.+_T^,_aϴ]jSzqOy%w]7NF͍g)u=PjWgTk|).nj*[Km޸9kctyQץҖ!CE $ 8:O1䁍"u㎇0"i=<}ϒZǼ̫y= Qepsdu؎m(hֲ5S&әJ[Z8q@ƁKpr<&>~Ƌ+QGğZE哮vo:mA"S1ltw|8x!h>CB7_W0kSl%Z07M=Q1ٸcP3>uՠg8x*{rU&9pE::ъ"HZY=c<i鈯Օ_fw:*Ŝ65[bk}j4􂫳N 04a<,\wzW 6: %Nxw;xs'xGpl\N1WxJn}]\ MI&)P`o {''8;9]x_}aHGW< #kqUXt'W*Ȯ\Bqf|xEOmh7놹s'Wip }'L}G[Ff(A]Qm8.n'QVV!)ObpSg|vK(:~9 rD Vd*hռ\OD䕋8t8 ѯw''a-\@;:ОqI|4j5>=; 3ӯ5>KqD&S1e *. q5:Ii5P4>zaԘz4Nhfx63z_ c/cK~ iu -(՝Rw^= NAйM#\aiY9Ziq}$ѣ=9 ;wi`I]ÆE/z˷  $"~Fnp{_z L8xy=a =:{l I~ӂkN!2F@s!f?;;__Pݻ("^|I|.պq?ݻ+.]B&#jkEbڱN'_X+ŧTbϲbZT#E{*qJfN-o}}c֥h5zEuTvT]{'=.TK}v!49hPZ\H7}9mli1֡1e\>tsyi4h8qo^8sΖ3xN^>*SbPP`tg 5)3LDS~c ]/g8tt+ev]骦rWP#2t+`bJ%Z9`Qk=^$Ĵ}Cu"0~oN3~|d2Y(~ʄU'K]QWq@n>_+&j^*-EV9g|GK>\!4ek7/lA6mR?-kt4h8p8`m^Uh {ڝrrZV4gJ-X[{)0ѫۗW? ט>VV3mXU9`n[[)խoq@qRLO*j7[SV4r箒+#Di+$lt}x ЎA͍X?(\޾]EO4S2sJL?,mq VQ:ncZZ4DVQJ7ק|=LiB/^n1C}9a^_䄴[ѶF/4h&,j%f۰>\v/>DZ5xeCȯ?~%Ie'ł7d+CR,Q=~ &JQ6ڇ{`3`'B}g8 |?~ك93'nr4pXYaw>̤f4 ):}zԝ j[2qظ}3N۪~Ʀ;eJ R=]Ҏw;wa㺯ЏtDnɽO}9L{^Áe-iTǁ*(9~tJ=2ƛZ"CtO?ުfPNa_6>~څ*u jtTWjCJ%:mѩmK&(U6%]}[zsy3FA0ae/J.cҖcFBj1ԛ\^zrܰC5Q9}V/ %ڂRԓӶJMB?EZ R}\ E>hWC'aոS^{'y]ÊnUpoYQXnR]ѣGjzߕ:Lnx&{f~[ 3'\Īo@ڨ' 1kGU΅. i6S+ХXb3|e&lڼ'Uxw3Jn~oEiM5k1SS5ՀQA,n5k91YʍнQZ>mlaٴTLMy$Q`{_~WXyM[¦z|Lzn5 y8PǶѦ FAX6W:\rΆ  wwxyyӓD eE!ĩ?WF=\sz -U`^W=Ж1{lȫrZd3%(rѪkO : b{Nz 7"MT)H"`A)^ {kzMO$HBBzOH֜pB?I>sfϞy3k֬^~{, /V}G$r!n?g_QT)e_u[4϶ߕ@cP^]q!j) .ѩ]=hL~]od|nٻ4{G'URP !mڛmq5LxFEWBɦ?Q *֠mxk>X ۖUk *Z ;3o[Y-&RV v̌1>;c$gW]t+̳ؾ~&ܬuq9u9}B{H7P__v7TviQl\}6aoN[an]CFZȦɱ=ua͒Iecى- ]*kc(㼚^n=7V-NxfD-ǔzмaRyp 閒L *|mi"fE??M9q yyzV/MPjk{(M[f&b$H%  1OK(ao̖ 5"Yu?)& 5S czLX>A$V|G'݇n\v9V d$F^lu ,G]wf1znzw͐^m9P?K,!!"dv'$|v.VY0= Zvus8w'3:yfxzޢZ\-E1}rւm;b*Zs'324,\`2wS,-l٘s5ELtͮl&rp֓Ѭs󀆍s"~;gK2)Q!8q9ViZ1s\ChOb׽BE^H&ʰh6iV4 9I ."(֪/ %=C{ҭ[ 7*aR.޷YQ<ˤ~{Y('\`%mVWL&!.^b%v#vb^']t|`9/&;B\1Egj>4YO5O D4-HNVpeR|=7`Rq~EOxJCjlZ2]}x3dG^c*_̗:Ą슕E?ç98BoOY $LmjGV.5G;}9s썟72&._Iz6eʗzYKFMʔ%۽^w2lel9kSt~y ElR7?wWӴoFzx0\X]|*s|uziZcLۋToֈ帼c%wb<Ba0?ɑ]G%GJ8t7UZax>zL;Nn˅^/VgO!0-bFT ? ;Y"#k\mau$$y|=~"l݌Ԋ#vu_0#.uDo8|fdݓ yrT(]{?} ok"J2Lzy#F5{[6X4yʦS̭{NĖ5D|SHi*| MLVT.bSՆZa,\2yɺAM׋8,:y0y$&M!jB`I&?Ûؤ( 8)gn?!ǖ/N!΋vL3qB6eyşdefځ;ҡ "M1 ´IY`+ u?D7೩3Iopk`Ԙqؙӥ@,c|ٰOxS6ەbH6L?;Y3b,+8S|ҮLq-Uj6=O1W,nѼ%UjBL/+|*rtngBir &^oܘ/жmgak͘;l|=~1 n,XNȡ#X;I,@C# #n%OUAJE9I|>3 S7h!SB1s7ٕNNw0'LLfΚ鵬s ǒtAv{2zpFO2Y` SJ0g]v7-%*vfx+%F}swnǠSq }F \θػo/B[AKByLm X?y)9"{{NK'c"S _kLn|KܰzN:oVC7Ԃ 3]!޲e-tTS(m.m1D2ʈg?:+h'0`H_"}NB1{ҧLђ*s੒Qf '>1rѺ"*>K s?̖#IJM'.Ar"-E97Ƒe--xso$J9cV*ḋ(_x${NnU 07WHTV/ *ml@ Gvn$(>߱ݮT-CNR=ÙWI3Sq$d BDSX0cV*qLcؽ%j)ryP>UML~{'K(B)ϣZإDeD'0"\XdeUZʈJ\ kcg~'qBM4ar{K3CiMQd= 09E4'y"h;OSc&O]ur? ',r^#1{"c #6g=ʑAGڿ"H^l-3G{rRcٱl.;N]z nƞO=-P 1ʊӡQ̬tLli爓]nB 廱qM U*: r`O4]~_̦0 Ud}h2RHʀj;Һ^I\&3mmD{Ϩ[,12r8EXzI'fejԨ;8{!5+U")jR)']oxRb#aeR^TR6)X46blaY՚&rvßT)6vViHˎsQ:h"M`nDlm.(bcN Kꗢ|.=WQZٻWM%ضiQ^~C}AL *F`bS5k7i([9i>~,X⪴:aZ0^O}0VؾT]e/ӇSb3Lcm,P#=ao5&ݟ k(sP64oZ_=LMp*c鼩GdӵU|\!+e܊55yKdkhہFqMISY'@2Hy>]91I7tWVg>+l:MqI/dъΟ&QD<|DX)?X&2}WOS{f LD(S$?~HL-K֭c,0ۗ0-V]{sl%@v#3hzLe584cܻ^'~Tj1SX`P( o$2 TĹ+8G▤J82c2~Oh Wn#,e F]r]&-aD4T'1FYؾ^Ia,)X ؗƜ%p=uEy:|γ;odͲ_}8fOB@TR5z|(ui^λ:'Ǟٿlء4TJ)G@le.ڽc-QIo֙4+²-Iƾ*krhr"ىڼIvRi]~ݵjں[()CAbW4Pt5?RTƸXoHtJ6{ cǎMd4:\?݁:rQj3^=&4899My+Hrԫ]K|z;Y[Bx`[4YAZalw/k>8i9(k>X Xh ͓%v4{vqYъ sK3Qbciۺv ml6!ËX19ɑIļ0}yhũ7ehh)?@tX gZ&'3w#6b:.c%vC箊1p#&͚bqc8.Z`?z?$䟐|hξ8\e|C<{ߝ#i\ǁL|noSF⁥p)>G{xy!vOod Q-rnɄ^Β-evU>5'e}Bn(01)AQ 4WVAﺊњZ bJ#f>դۨtJ)Fr~3|bո0rdJDLLD1U]XTWɠ*yOyV3CZ[)b*Ӑk=")TFe!x RFuOa*?IVgo~ߴUzlM׾.뜽 W{bSL֠6!XU;}̎>ऋs[82rP#gS/>1cZ3E>Fq.>zs+?#꛲SN.ukIC@CG@j,Q㠊$x:#5X;~ʌHkPPc$|Un5D40 !Qs. D IX&yveKYPa7Cy> %EP af|_ SeHT#Y`~~ 8OM?n\N)ԶBce{7!-aޢb+WN|_ӟonq!#lD7b&sæ-;daQλS'ԏEMVm}E;?W(Ub9 qgql+^P~o#svh5]ZMTB%:KU;\&(gmɯ!;ڠ]CC@C@C@C@C@CVsIDf7Vm zp\4w^z54 (31],iTTe?LceKMU&'j˫A@ *Zs}Uǹ:?v}=O|dB@ٺ 17B>g/:V h~3G_|";M+[^yTekhA 46)'¢ri\ϜOc&NPDU^+[j ~` 1 IDATJ5s%Bc$~2q~b»CsYNIH{OTX-YWN8İm$MnL&shv%|iWWNOͤ'==zYNfs_Do0 ʋc¸YKX43Oc9 (%Q%znVSm(˪qe% [ʹy/WLv,w HMs44449^lܸk9z!yѷmC$vyWT7z gPvk[,ݼWjwõ@#oLFryé'TT.svپ*P& c\)KWΣ֠;U!!'x6K^uG2{ \wJ5f[ z @;E9b$# ?w3p*+TVZBEIё.} Ja\vo}gxohҩ#W\P$xf}d fy(1AYkv!!!!G@+9F2O}Hf+[.ܪ0C`ϹdIK d$0D{og0|6, bA$Vk2?dnC,1D1]n.Ժk,XL" `N˹󘼬oɈ1c^Ma4HZS `bU݆Fٸ\B8QqjPz}1}|$D :p?;lV&pJkԦ5FGZntŒU'D{v$2~1r3E>DGѷYEEe0l@?rH,ƈ1_6#631ג!ͩ\ gS^[fN臗O%TLfUQB;m" *T*ƕ?Seo& o'XI.oX@vV LժX vUgcm {r\B#W!yHjU$ LƵiױGVNV!GxIU::Dl?6--#A1ddHW[ 8$2 G62ɩY=`f~>CXt2MWqKwL4gW>5VFLP0~`y-x)jb khhh#P>PG݌<7̙2*"&$ax.Xg!B8Xs/sf %\K'cnig? ~k$T" Fӯ[gHEdTDcgCEuus)ٕe#sTrlRb254-~2ycNib JcdWb$oިVQwL4"Ԛ ]->=hZl9pѵiYepU._̃HU*NhI)BmZ66\x8y҅qy/bqxg K44444 #X MzfLGV'=:R0J^u=ən[(32 HqШx4ݍ }ðxMD]P@*Iy!Й\8y Bƒ8SQ.Ç?;Sj%' E(ߢ41N!!GxIU+;ާ`'ƌ":K;aRӿJ}%:4tKnd˧iPK ǔho_wQ9d]fҢw=E= F]ޜ9`˄ЮM3L+RR#\ȓ܏.^qS&#q94Zdp;Љ&X|>?AV4 ^$i#U!!!D ;+Zn,#}xH ؍*R+8ySvk'PIwDbU2l+P>U-m$9P*nzs38q >kM%:s`RêLJUgz\kaS5&-.S.Cklߵ;v9NjF1a|?m7wu)s p qܺxK7u:[-*«@+hhh_EHYsU,Er]f|C)Z2HLAN.椫;ʖ!'Ӿՠhpeʕ!2OMMI91))+Gp玐A~+~s*L?GD?K1;wh3ŽdMQ!?6 ?)T}g5A^˚~}?A2̈́,+Sź̋`$°25a<˒~r]elSC@C@C@C@C $3H?ee<9X7ǩ+2"W1C#rrӒ_*P*SPM /&|_ nߔ>=]}jhh%XE[jb"sг$?R9Cs:|PyCy[kh9 l\nݺ3nh5D=== /"!!!OB2ExIENDB`diskscan-0.21/progressbar/example_output/demo@2x.png000066400000000000000000001264461456470715000226710ustar00rootroot00000000000000PNG  IHDRr{ iCCPICC ProfileHPTWϽm;, 7UTRŎ(""PcAD.,1&sh*Z6G;,tz':]C{9W #a\0A6&)`Z01ØIcU&Xgl06 =mvay'Yg !~ @P"< B5p0IX" UD?b,qDN##H$S7)TB:GI'}$ vPr* E~H~GP)֔J rʧo5?_߆&1e;N2QyA```-i!PPikBTUjGeQRש4,MBisB†e—yt]BGDDlD"E4 ,JZF6~s;,&D-.-.~RM\%+q^$,.#Md伔TqkRtikX"32TK"+2/eemdeKd{d$R*U( Q E s2)JJǔzU))Od4RTTTTajqj'au#h2F AM&GJsTeը5Mvn~sXW竮nnc=!=W,N,2G]o 5 # O>0y36blb5n21Q4 3)7e^|MS.Ӌ͌RΛneg`>Ne]uLJ e)KӪ깵uuM׶\E;3v]({'\~!RlF9'#mN]g7Σ.R.,z9W=nd7_R\Nzm/$^e/||R}76.=WO X , ,  PМБ*36$)~ӥ/a>3=Up9UuDQLEdaTETa4ۂ}=m]=cS&9"v136n9>09qzHo2K2K:4u$CShȟg_jwiiei/dfp2o=u*1mmm>fGNhg] wMv]'n/YYY̖ޝ=w9|9ܜ}*?`pt>o}<=94rp]`af#EEEn>zذX1^{Iq㇎...-k.,?Px"IMRyNŜzPTZ\U|{:?׈||zM$ ƙ3gڟmojl7RϽ1Ǒn/0.4Sy %j:knp4lYڋr. _*L}yJĮ٫ݛ_ vǻ7o\r[f:n3n1g/-wMt+7^˃+ER)U̼m@= pHYs%%IR$)iTXtXML:com.adobe.xmp 2 5 144 1 144 1394 1 227 2015:08:29 19:08:54 Pixelmator 3.3.2 ץ@IDATx |LWO4,H!2Zi&[LPomm4%m2! jM.JX"{͝v6̹>ysFsL&#O$x δJA@@@@@@1V|[i ӲL2Vs*#a]R5f$AF11jR0dLiM~h K$'c +(NEI0taΑ xs5R5&86!rC 9 H6Ԙ?Ø#\LA[xkmvd3lCcBƾ~y(+ m9xɼ0)Oss=iX)h n^xG;dU4       ` +vj,8Ý_isncƌ&opfosҒ&8-j|>&qoG+!7/ܓLIHRGB-2Ըq6_Z\ zB|%1YV^VoK3h/M sY&zCV,ڳ%T3u=ë?Z_VeG~}2 @@@@@@@*J+Z˔~K;fE'^2U-suES" 2RuPק6{x& |:)]9z Bd@@@@@@@BfaNTȥ$oֈA})Gf=I˕}ts{=! @@@@@@@L6a~ƽK,=з7@V`aHI[<a9g]j y0%@@@@@@@lG{+GΘnʴn‹[4!J_)sZWdyRI⊥Ԩ9?4BVLX2/-5viɣ~;d"Vՙo!?OkR%̮ٖ\}k+;Ug4(#f%41JsN|2i(@ dztk:s $[&L}+VqK,*="r*2o^Njup@@&/&zAA@@@@aq   O2仇 D.Z       ՜ y       P} P} Z      ՜ y       P} P} Z  "<N+<x,jԨc!   O&PSw] <_#M    _N  `;       -)jRPPY}QɕQݲNLJU+z$BTϬ#)R>6r+WZb12X=2y_=ƃ~L&MOOhBI EY)o\=)^ӨKIY\֮.$a>35;XPRjޡf7XRH$7 }zYjyD0=b2foWɟ nuqDV Gn-JS,(YV(0T5c]7OPc,kg% \bM!%Ƨ*]b8B*A@@@@@*%nHC+}S9>0PӃ*t;̦U"xqy QQ\L=qObNHAےr:ԔPkGPG}CKJ6ûVII 򕇶''kiCɵ$}-BFt }B֗Y.bg\L-#;GW)5p lդc$F1)\L!}sl TL Wt+V9{#k*$UW.`r2%~fW Tkg~R>blkΐTI]Z>+##ƧK٧%mÜ312eg,QJg]3'NWΛTNF~HVt]'So7{nhO1xp Nl^*yM`S ^Iy;Mi9kehW^Պb7C0K;Z Hnzl:^sMA̚[JǺ8  yώh;g^{ckuӹUʢxyOߢojD: ݭ秼㫟"AW7a ~=ĺ}EY vW }JL#4%s4;5CWAH~&r^m} ;/Shzc(XsӳT)p>_eű7}D˽CFYIZ 58844ċ-9z671'!\L=iryd@@@@@@lEHuIZ ~m/b^nmZK8$a-/ ٧Ga$'¯ǒHm%=T }e/^+5+.DPgc 9維Z`ڤWe7|1g+܎.q2t=tVTbQNڢa/_mEy3C<]Vx>=9+٦%%j8Q9fJ{߲/ ާ[✌=]$2 ÿy;b~~nn6O'%+ʕ:0&̥[Ȁ1 ^ooo0ĸPa(e]9ǖ7z6w;'Fށ KB!ĩc&@B|þ֏wMBCGO1 F,FJ{IݽOCM:l6O zBu[T >6iF|x۽Џh̫>{tgLr/UUqGfeVߪ/W$.#.RG*ԑ<:ؿo%7,czeu> r& |:)]9z }u#?S=ap.@KSH?2*Ν֘-_Ο+c<80.0.0.0.&GǸѸ0F[咼oDk-ې n pj\7K6= 3?2Z5Wh,a\rPoztNԿ!R$غ9>[05r }.2g.:\56gHzWKOv}eٛjlL)!z]־*nMU>؆?=zޝ3'7o}q:`To6N3C8Ce2&4-ofbRɳasvQcý PvarvB'@2vI5tyKZvx f2UPI6==Ѹ*+GU?UҎ1y&\KRDԖJ鐵i LWtIʆn5rҖ4X2(Ь}TlD/?[L1>=-jDw)bӅ]9##FF'/avm03[KTLڴ}#;]d(dL 㡁qqqq!$&7A8"<ƅExcnI\jЖ]_5lE33t'8|P֜Z+X:oޯ-}"WK-&_per+[1ȕ3ƅ jFCN>g}ˈT&@UC)[`^?\S/\T¬vco[ɤUJ1WJ׾Txwf {gg?_ϝ@|Lt5 ݂-B@@0&qqa+ c"DžqEPijh}rNS\v~/O#g4v6nw?ʹ/fC{,u}s9Hj՜r1IV~덖n5^5lDN2ȹxL#S?"L8 ܂&"1I[?]- !yQ {/g\p[Ҭ+؀#Y$9pœAfe,|vi56;l_ςG֩ϐ1|77 `\`\ }}}Øƅqoqa]}EOHwrr*:7N7sky4pe/w;O`6eP¥<=9Zmrg0!,oq-[r1nI{J F}vi/S ceSa3MLL8'1z,F7bhi[]6@n>͞>4-Ab^R񨠤l>°LƊj@\Ft*x`b3AeA:6)Тԍ跋^\Թcc%sa .2em.-h.7DbXS[ö9s\qޡy;'S(=}.@SzMĞzBޡmU"&|RލԪ>d )SmmDDT#֓*=HQ:*[:bJgs !Y'ǘnqմ6{Dy'R%M=%u\Y=-ߎB12b̊ң[%$9Yo|aRyxm";EWv&-        @@@@@@@@$LbA!u+Xg V0        `$@@@@@@@L@X$X'uF0IaXP       ` A@@@@@@@${-+eޝZѺ@^IHAAAvFRjf5hQ 1g@'U?%,ͭqK1ѡ&S&լ?&]ϱvcCbR56k"rFGs)T\Sv+BA@@@ %m#)R>d7g z.!FJz֬Y;G=vN&榧j+|] 5SgD\|c侮1)^Ө&%k<1i@ap(+փ G!lO'tjN)wIZ=g yMJ'R0*~.ωfb^z0ZgyMJa-8U+jul6EUЩ[+6k ]]H|fC[`Y-mxͬn%wY7)*HAdQTYڊʄtRUCw㺏 ab!cEOޥ}nΧ;9.2BoXg``iCkq/,).+ryh 5vzYxA$_Pf>+Cڼ*qgDJKĉBՁ봥sLf% \՟^:uF888\KOȃl՜PO`TSsvO;齃RrP$lLY{Oje&lȶRʎnO~(խխ=վӡ    P1NB~[⨯Xrx53T_7kϤ/vAz>b wNo9"ȿJY<$Og&uT51zȈ1'Fϟd;1+:dM9 Z+S8/MRHbZFbTf&D#^sU7Ŷ)+R͎sȖ2g q`| 1V`&5D[9W'Ow/*f[MZo3^1i][yh ogxGR>odyfn5UæNJ4܁EwKw(ʖLD));z'FyTBk=gX߿Eg, \QޭWZ%k4lM JM~OIČ/W۱߷K/l 1|ƒ7Mp3Ҷf|˸3g זؗ\i4a/dsEJk|;~=%Kg GtƲYm}6f%_mbp ̈́9\vgA d2R_'=86fZUf9 ю>n碈bcjp@@@@"Wg|谶7>`5+S/XV44. Tk,?×z-򋱌cET2bdYO"=okf +cvO52%lܽ泞yD%8n~;SB皔504yxxLڀtWbKa#\/pgn ']psWTNjc>ܶo2FLӹGCzs_2lI'mDPׯK!i I\7؄2 g䬕^y.Һz<_| fĐ~b~-&+zDzrBo}XӔ2b4if{_cq۲M唛:|о~tIЙ޷{miɄ>3-Ae{x]/VPLf@Ӣti{GR+(I$7}-|sle"W\cZM*Vr-V|Oߔ+o5i?"jZi NTf9{3ծ%(2Y1z-VVb=ᢣqg槼㫟"AWK7.`/ǗX#xp Nl^iLjK 0+<9-ro342C\>*X ?i:m!\L=iYcN=V4a&S8gϱe[88)dnA엇-/H2I 'iGyM}Y)iQf%}ד~`u粋I)a҇s1m͋cco>{^*ᶽ$Aaќ }Rx.-m;g[;y.S(ιFmTgc 9維Z`ڤWe.\ .6&&ES(J^041gyHU?I?V0e(v!?vix1)KX/66Brpp߰81j ɋ`hfE>&z[Pm˧ =#\G繈Ip'#RA]VB_v7ɋ;z*֦Xk-}N f Bn_fCƳOǏlyHN_ F%voH__~}r19>yWŒ]eSՇ߿XƵ]J/Vs V?d!c Q LCW^ps}oʽo_} &Ž|a;Lهs8>smLMK!(12z+3; p;lPʩYYQe1QBÜ^T&e@(T@垜^&%j8Q9f~s j<[>\C)ÃbR+s2bVR1sGFtsIU͔ V|sF%WI`¸ANpw :M۵Eg% ukI'>\8И:s4˵oK{߲/ ާ[✌=]$<_xI}0ӟb֨?l>#|ƈ)69t8v /(+u`˜K7ӷ !cƽ+A@@0&qaqbvmrt(ʜc˛wOP`=ѻ#u%!s{YG$D|þ+7,/s[`$B)3gإ=$ާ[A >5Bۢr)'mQ󰇗0ɚg tvw@] \; qY2eQRɔF%D~t?lQP49L\#E^(ʋ4EwSwGϹfY121$1iP:Ņn"[[ޝlS2KȞ܎#WT"_=|.15]k'cu s1zȺ4g$߃-Xx}L:#l4IoUS|c }"mYmW^I'zvE#NҸk8;=̹B'+r,;^8yAY0՟ D14WBOqs(ad˷8 }ߐ5NzisYzGmkK@ܝ cƽ+A@ߨbP6fJj4FKe>q_WedE9Wc[U w<[3c8}i,8s~=:Ktnފ%8KާJwz`ZGGw_j`L򙲎Si˖aܳb w _ {c ff>C;?iǧe L$12&/RG*ԑ<:T̿o%7M0Q=i-ma)E_6DnP>zoJzν^C$Cz (_a"wի͘T9# bT87F꤯wEoqiw Q֙IƔ %J^Vf\͡'GDӹ 7xn|^RTsk)$7!g^g5" ֯|߲-sHQT xezk*uȘ c<80.0.0.0.l Tl|7c{?:?OvzjC\Co{ϠH%D F,a\rv} N5Z 9Aj1,cz2@3bl3O."`d'경>kuM0eXAs_KG y?'n't? FFPQ\VpzU>؆Vh| T[-ZMѤ b Dٷ%fHUsehaPb.sP\I}sJc`T ) (GsD"ʛҥspli&ԫB5tHޙ!ZKl|}qTU]8>41¥#X?9mac)[1 늗B"$𱈇#a W>c71|y;Ӟ{h\ -pdk{OХFblϥk,#jK3{r®2lc k^Y>в g>VGc@ǎ81T4ê FMٷia!0Photy_撡1? h(Ƹ(ƅEx=3ה&#&EW 7;08[уUI ?KkG+<56E(+m2c˸W>,[gNAM +q>׮G&DNj 3E:Mz5GΞ?;=cCțB#mNsIRYd]6x+_Bt?Mhl%:[ VlÑ~)4nVn*#ԍsn5$5XYùxWlh6k*¹Z/4nw +:+{{je=SNRw_"%*PbcgF~Zӻnn!jC{L%>fZ?_ϝ@|Lt@ ݂-B@@0&qaqa %毛353/?圲?PRI J\:s͕u4LBV:'3y>Tlj -FAmVYblQ eWf{MqfTP:ڔF0BNM9wlDQ$Y}DnLh=zbd4wҲaVΏIwqmgXblrvb'z?[TT&?ݛ9-Sދ~nGv leeDH_4CoCduM-7+H s0g: gi7L ! 8K$5rE }D+GRhI'-9u{'=1g)'Qo|fzj>NM~9DaL¸Wp%UWާ[D Zl''s?}3{ t-)32}KݨnߊkjgT8_?y¥afv9i?&B=e2g]bz&}6u)LSҹѽU!?NL.\lAwi$a>3 ݸə{}H؜]ȴǔ^>ZO_Ž)pR2" k om4~yZ"̟1qO>:DTQIդoJ5|F4nz}MBޡmb   I]e_|~Hl쌓+(2 g{حwY1r:}JwXuEy04U\AY[4kЧ䱆$Ɠ`:gbJj$?7 c PoslXʾs(LjҵS |y_9cj-Jx8q]|%t($*ϊ\f ̤>\LA[xa0]LWa/ǚL )r{_}&N79#*Wy/I­ӻ'uqY"*Lrw7/=jrfm'ȫNs[a#/=D*ѳU{tϽsg-S(y;쓉t*tTQ;TJ)QIwblT懪T_۩Ωcѕe "DXwE^ȉdUYqŰ|}CαfHf?G*z֪ECuJ`K8W%+d89#*Q@@@lLIۆy'RǤyN]Rͥ6/Fc%V?CZ[{(mXJ@3+GV|<9,>og .|ޝ xT- ph*<\=zZp6|vIM<7Ʋ} /     Py+TjFjƙvH^/Qus'{$A@@@@iXL~\<3̻NM$_gK,[a,g ǵ@TU       O [  4q Oͭą?Ma8SCs"W#% @@@@@qϬ$)R>v2[݉Iry zxy12(=R<г^͚/&߂9D`RܵnFHoi^(Q򲸬]]H|f P     PTo _fV7ǂRwY7)*;Vj4Ʈ,J<"O[1^\bWɟ nEd/D@IDATow㺏O<>ȽFeLea1|5=2otiṔ)Q1[fDVmŤY<0+dTʹҰLPaϮPU3A*~o@OoZ.CΤе(AO9HWXAȖ~ԊVy(P߸QА'\E5E[j9hDwҺ87ejR!LEeD]޷vtԛptfNۡjg>@@@@@@7bnBokC.cMkURRBv|塭I}̌xkirDנ}Bs6XSszDU!A |>[5㘥"#FF9Qz 5oٝ®}ߜ0 ؿDT1TQa'%       cPy&e9q"5Er$s8h,O5)W      *Wpk|M G<7ؤLAʴx̤@eV̢3?|D~15WYLr3ԏ=~H(Fyd·I)ً:XI 4 W.B1zdda~n_r1PB^p,HN[FcNkAbqdf?:G46PmE;&DҬVD"y;桯 @@@@@@" ٱ;g^{#u0uӹQ=}?~z>}IǾ^'\ttW~]/Їzm 5kRbzcb;ݧ@_bV=;5k<سy}#/qS4XQ7xs[h]f܇l l鱽;r+9/'.S}-"kYNۚ \? $A]B9os}4 jv Wu F8z%|x/D@@@@@@p'#R"ӻBQl ڰ~SíM?Q'G$b&I+ o_fCƳQ#vz P(Bwn;Sܜ=d!]|]H|w<ѫ'ħK,whIOY}n~0'zte5Z~W v䂻#zT|٨QIJR zZ 3wdDxd^|Θ`.$ğd2ɻ}>${n5s2v0=s̴9,mQpڒ!1G|77 `\`\ }}}Øƅqo?<.Ts/:iWxi}~;NȊriNj#< ݤ/2,䭙1ނIK`بܩ_|=VqYuCV,q^z>rޭcKo^ݫ)<{x7>Y"+V8jrԵR)A`Sf&4Yh)ww׻[7;(ޤUccʅ @MΝ֘_Ο+c<80.0.0.0.&GǸfU$$ѥ:MzQbzj\Co{ϠH%oS V,a\rPfå: Cv+KOsn)¿O; neH)c;璘co}cK/K"ٗ%A)ИByr}s^匝LlnVNwiD:#}^ӒM~}uHBY?L9?)ȣܼ́Suh>*Adnr9i˛Ul ,k[|fTtfL@@@@@@%P5)lήS_)2okмT:PʗOu!ymr%W)C W%T^S(hD 7V0җ){Mj3j npKz#X8dR[3q=zԅյZYCL̈́ٲqJw10y F_b|s|f+biRPtO`)rU{"WLb*+g Ԍw?S#A]&+q:BfmZXh:loty_撡1Ǝo~ \㢺`b{ mm:bBAZt}p=xP8ЧҝLbb Қh*+WLb< e@-l6PuU4>PX:[JX-B/m8[ʍ^VDqԭ+(f'J+ Ūwgwv6{N >&zƎnooo0\ 1x\7%tʧc}rNW_v~/OIT2mJЧ= ]==s߁qdlLh5  zuP\$XSD{aIe"FWh!c]9\̝J\L8'3"&e,zۃeWŸ5î3H      ՛@17 践!::^mZw]-_yh+{Rzrj888\KK"dDנQ d})"V}2sD*xHP'VM8fHKbcNs\٨`ާm5!qc2" _ fErN 졻ٙSS+l@@@@@@JęZtMξڪ6K> L?NҬ2p*Cxyň0G[x*)Ф^M 46LA i3I12fҳbŒ+y&wb{2G6z͛Vʒ<2a愗>cPy&e9q"5Er$kXj"JP:9Ⱦ%Q ^ mҷq *XI&4 W.m PW{bnkZ8:}P&dJHWV Tklx/Nnc[s윥HoLr3Խ<~H(F1>=&A/?Ic b|s J[ nUf^nvM|/J_B֕z ܋ouĬt9 Ly>>  moj 4-1!"fw$"&N"yz=vDVv{~h3ȽSƃ=g\#/qS4¬<9߽WxF:i#{9I*^5@@@@@@_&07GUcƛ4/O޳c#jكמ9vt.AȢg=}US$}XOn:?_ " +|B皔)4QsbR!F/nGuvu=|Cu"aoF Z +H13^8nt#jNqR-٘Bqι>WWAn峕ºu nw ep= OD,W?Iᣇ4w2zͪǬ9yWDO\X ( Ul8ʔ#     ՟#G|^+\Ɉnjj~mXb Z֦YQ;Il 0rx6jpdN}zᶣ~:L~ q> cIF{fI=C0n/տ̣Ef|]YM9WΉhNLz tgLR2M޽{[%0AqNƞ.fÿ7/̣ܓmݑWsbD嘲$9i=tɚg tvD3(Ы8˄/&@@@@@0͜Qgۊ{6 .ZkCα+8;w;ho6$/ ˇG2G^a cet fu ِ ۧLj3Wivr1iViPGBUrfЕܤm: zBu[T >lL"xhٴټ ^ kt&OY[)coI S1 AK~^p̨zCG-z.СC''0ȞWX-_}PKd\${nh"?h@a?#g')Ѐѯ{)lJ]ЛHK u~^9ٱnZ-aMEI{@fH-{~^<^i}{y?M-e٧T!&MfpBtO˽0e0.@"jtҽ=bdmVDOá-i.>VЫhLDUKI_:}UҮ]w/8rNRG8ag{N==ؽw&pQUoæH KȐKNh䒆ZXci/hO sb)*ML4-TTFQIA7pAY{g3rS<9{s{ι[9˸Q?)߻.R(OPxzTA @@@@@?Is.;U(Qd}[܆YH~F+"-l[{KWҙ;q ԗ8>*zF[衑퉞L ?xEzl]POܘ[!3ewIY;p]Ɋ:s2_cnRbvn̊'wT7Lg{Ic"[B|QpN8Z:a7(g(3PЁ I     2ι0}A ̅ MmRyS?Fnq q{=8SW<"c^mî8!?S[C~i}衑!;ϒun\$cn&XQ9)a}h*~E>A"BA.\3;΁r 6nc#Q,۴,҆xb{$L"5^mbo4ou      _/&M^z&sEHWb1Çk:dcώ41k^vOǕerD}h\?=c } ߁H?6oVQy_\6J*sܛ5;Ȇ <#oYRwQM kD]~T.`l.fF6;GFG+xd*Bkϩ_p..X0'HKV2Z@D+ >Z@D+ >Z@D+ >Z@D+ >Z@D+ >Z@0'@ů#uaF.n~zXM۵pQ J%sA+ٝHKAFFzI&skI`t3KczVI׽ 8};rRQJN||>xɿ}-gD$}_~1/O>ǗX~o1UDϼy\=A+~}{T LGGql̽[|[yno!2}&byyFqY|aObܳ\ǕkU sO/ӧ2wn&\&Ov-Eт'Dr+,ڹs*\7Na{ w cLv kL;U5ӏ͕ |[EDa Ic=i]!;ב!p ;$=j) uogSmal]}>-QCfsLu St$IV oW¦]]kF4u7IoIxxE pmQ  > \ }QW~N/_奌ckw 衑LzL4ehIA$"h+%(AA @@@@@@@@ D$%(h[A       V1mp+hA@@@@@@@        Mnm"Pk*1%c\;TU+Ӗ<5S=mWP@' T2v̵TYALFz]{VX XH$bÇ9-~*+h X]-qt~7TJw’w vzY徃 @@@L?UeF*NC#CS=A˿[8i@Wo"3]K"^\\:wwtvq~6FN4Uݩ0QQD҂M,tmDZm1զ   -dcާP'r-~k؇Z&4zhdh4AO2JSd@@0VHZjʕ?W_r%I$~YXrStYى%qwU+5E_ۛP    m7رc9WH0衑FϩY?FJ;v5!ʏȀ@s#`|oL~}x!CmړEinBZ KZA h&VU49ʒ'x9Dw&n,TzLF,3e7M%HC@Z<4>$~ͱsX_}Gʢ:Yyg?=틉ޤHNSGrY%s6gE5bF%oޜ8ȓ [GQc~*fSzzd哜R")4ŷ-`A#eZFI|-Mg,usV- 4Ky)״]gJX)    @OS:->Ď//5X؊B'C#SP*J1VWV  - 4~y/r &ފ &+Lޞ`6ʨ[cD@̩N~!<9j4v݀f f]mz3#b-D+ש`X/p"gr6fOc٩?G7p^{<:屎2 v&2}&,\E钑zt<3JߓF>hCݹCrʼv s, V<1fe>   -@wWY}dO Eղmz$4z0.͊sJ ysG0q]h0K ]>yNs6+ˉe>mۖ&;QtSO>8)CtIF^`g}| uN$OJ͈^%1pOt־}9,nEQm;Ur$?ԏ)2 ֗T99fed]*KUwtL'})S)9'F|[4o0m[+[AD    'p: Q-ڌIhȐQdA24'ȢN~ol4$@'`S^FƓe$]O~K>y۶/N 8\AYfp_pp7b+=T/yrt'}Mۖvה0ݻwڌVʅo~S/j-(ZUJǏ2I;_3;p0?]gڪسb!y>?vC .[r팍^WF@@@|wˮgN^>|8}xHk }=42KG^(7WM -yA|5$'[ٵqSG'u¥_W`XTeJ}\nHXwDi慣89?Ў# 3?ץpߔ 2鑓gq+5Eur /Iz;DIZ\,U>֕( a|Ug[ =&TG I1b_LX4qX\P@[9HDԲ"y|#mpl SW`ƶ9    pyEmkoYC}Φ}Nw⦦Ә&==KagA꽴25)bƔqFrtx@ ӭ E|zp ֐fRЭ2F-*4TГLlvFiΧJewNTQ% !95%Y s]X    `.% GdyȇSXNLmi\aUݛtZfOW̮)DhZf@mŰY39|)/m *"nw&Y+Wd|VV+p`SBr1ޣi}   W%e&1N> :j]Ċy&(F|,=H6fƙԮǓfA  A@@QT30d}Zb>F+ S$J}=42jPң[0yֽzZ  pq+س{5ЦDDٟsosty% yij6:N)Y'ML=p6wph}8d_V89y ×5'yQayF4*pw|/C$O}❏dK(3}ȹs#w.հh^A |`J\?VIDM$4zhd5.qΟ6Ņ);Dxu|e"  osmkj®WjnHaWz1$Y<9Wz{=j!͙;rWܒVvmmuV¡S c3lVҥEm9C )_I>-T &*Dro:=}bt]˾xۂ30rS"fV5_w ufi;WCPořu0G(."/E5[;Naok Ih(Ⱥ<zQQG&uU'cFS-UZoh&VS.7yp 9u V*^ָfտcqo&1 0jNɉ)T\ܻ~pЛ2ȭ4;ռ\A:=+{%*˩WP^-܎RUY&! >ކ|4yWU O Ϭw9ד}FѬSDŽxUf     $PĔBnj;7wާPWU"oy q衑QȺ .'ˇݺ>y{† 3" ͌Ot{0qL5s##)Ui59OTW0EGd(F6,$|oIxxE٨@@@/qRƱM鉵btض衑1C]ۧW{VVVLiQ֞ I2}f{^0PnU</x[A@@@@@@ MjA@@@@@@[c@@@@@@ MjA@@@@@@[c@@@@@@ MjA@@@@@@[c@@@@@@ MjA@@@@@@[c@@@@@@)z%A8?5l@nߘ${Z;mC:J_3uQJI s/:'15"/tV_S.ƅe]T]l64=&"  @M@, םdk٩S衑1\zh <,$ iÇ /1u+C:ׄ߱L8hTIg6.]\hTC@+n9sno>RѵcG7פbe'" Gsi|a;oo媕sQκOrA{zCew.4iKo6o4-}h^nKeTGҁ ! ڸFo%i8]=ݿR#M78 ypTIrbCԤ38xw dI-JT?kK"1Wke]=&0ߝTYWu<|4nՃ,97?0=424Qyt ӕ{n 4o%[jZYړjWȹr#-Y߹Sy;ۧ 4'<.٧Չ#gKN{֭4G񯏑tR~zq~]F~.VR7\7ܮgfs8˫{3] dɪPq#@œ"v`n)x'.~2eAɴƙQV0Yy5+@-:Ϥ}hA@YR0-aQj~˓gaogogN ci*QLВUc=9]'F?v_W9/0>6>AKz:Z3'VfY6ik>ufE͝ҜOfR\*s؀Q Ź;=i̊37żޠ]"  " xJGec_QS0,l꾜^=.bsٵ⢢UOE"/  B ?gvfa6zxbQEm3U{z;mz3#b"ѕo"sI_pe? q+P;e,F-ϓ]/z^=É&1/AMe컊1Yn*E n{&gcO@^SO|>>Qɼk7D5.hs$-3s_Ɯ9ίy_ L Tū.?=ˉ;99ՙ&MRU6GYuÀS_K;K9|XAԐcn}y~ Ɋ& Es -\9}Ԑ5%!Cyyow6)yQ+(]t܏v*Ta[Aeݹ0~ҜwOvgߒ4!^Z -@wWY}dow?(,;;FOElΌ}otZӊNAؘVMCxȩ_d?WR?Y!C|]9/p>>RI_jJɶmۖ2a8/ [i/35Ք-9>22yn]ezx >S8g~15J5FŋfdU Ogۗsҿ"_PYt_vxT)LA#X# sZÜ#'ϬKܾ\̪e>x}Y4T|htQ0|0q*S/{_l(c9T '۬$+%ьi} uU6\4wt &yo"8y} slP0/Cf¬ˎ} uUWH#DM[WuRosa9: Йضk!Rxu "@@8k8ׁg7Qo/RY$@%`|SrfD\.O#$*c竖wRp 7 <NvfYmW=DYI ~zF=y>AUxsS'tb~̴9HJC{'%GS2;9{IDAT uι|gXVO?ACjΧ)ǽ4g|=9vd^:9McO} edF.o bf(å!Ct4s]wˎ| Et>۾Uϗޒј0hv]Th(ɼ\5r\BQ'%@ ?jwDNlB`['9&E4M$ V5NN+dVv]&Śj!z $ZrLVPlɔK]`t૱xƟg&y!v)GvՎyq3R }󣝓ʙ:w+Z@톅k'0G̑$Ū紕]޽7utR}pҧ@]E&dI=Hsލ[#:oyA@L&qa˿Y0x]ZKG+b{P P@Z dO;~ۙR>}T|b+R+o/nKcUn !=B9ulnK45PZ+8[ UܮT .R8㋉݁Ec%G_|zB `qڜ~d|`Q5q T7gUroa!e'7R7ȧ OMCamWQtLf.,|Ӈ8j]ߙ 6gg#LX Ǹu"4F%%Ϳh̀8zЉf?tSι\ lS΅{8f6@@cvXض53 MݗJމZx6/׸C#ch@@ZzGF7_ێp8 i)9wF(k!?]BaqUXRU|}PɲK $-eLv>@'4 0T5VIIA9Rϰ0=m~/vc3-?8xLo);{QaZ5KX#vFsnCq5)П y7  `ȘWI7nّp.uO YуFъhNLt+pMO:}ʾKztFzʧ_1띔iP*bkf~9046`[8w`V91b,| 7qƾ׈Usx#mFRe69pi$3ƨ΅I׺ϻ͆*#ni 7/LؗӫF #P  q+0׮ 䕷OkSö]:0wq*٘7!iIaCz~/HsJ=.7Sh|˒^ֿȈnc|F6UDo3tG`*CBS?&NStBw.s["*gp' yS{uF3LM:Rw% (?'yR׆r]U{b |U)edzN0\nA  2J(ڥz% zR+=8"Y,K4zhdNL҃(!`|j%qgP'g̦T~I٩?Jna]W Gdמg!Y'˔Lou)рd~>a.oVx2-n}Z[Jٟs+g7[2N,~0{W+QN4j>6r. ݃ yg{2$!r܈n  F $q  )q &>%Y5C#qu=lϊ\1z^UwKTW6Pps;kf}ZR\\\a>UKȐԅjFb t)8_Q۶dz! /#l#7*ʸfCzי^-l=*]S}̪{F?˞;(DO~W⿯XO.υ .`e#g?`.|QgY^vN"YrVwP0gd\j>z522̌?LΖ.ޑJ疔.B2$nl=|vN r&_@-E;f :Ug7NX}uZҖqEV̝ ;xҋl?+/\}[OBre෗F4.%qR>[ S)\  \ pUN.z>:yi0;L~ʌ#r4ùyNj~{{BISv>);?_ VnO ~ YpI#zRrRذg+'$0}],gM[K>>jʠي3O=]++Y-XSt)YS9=}c?c*5aμ6yeZw+i_IhV;F/ǧr''"(wz~I) m!oF0 äo}Y- ut"=_"[rOn ti9)bܧ FDNRg Ls.hARȐ=J3JNӄ7 'Drڹ>}{i(lnt]:t 4  4 2Y4a~aw~ձ?Z@A }Εa$Ʉȫ6L5s#)hwݸh@/׽Mu6%]nT2u0]koS q6eDuͭ+gd;k؞$h3)Э`HޮMc) |\^4#)\      %_0ήZ~࿴u<Ē~ݙJƎݘ#d O; s#;%bh_0)^髣8,,j/l{c8A@@@@@@@U|R.Р#!F-nvGҾ2bAZE{N1륁OA.s,]{]UD҂@7T[xB\^ׄILF M<1H)VUbQ7Ȁ@#@V8=zC5G>*رdGɲ7+;j~x LKy[Fu1+$jYr}hHTމ#%\]; [QPv(wGS d@@p+}9ljnّ<׎d {sLw'jꪎeYRU衑JϚ#$)]2S/7vȀ@s%`ܭtҳ?HՃ!<.yA|͛7Z$L Z/;x4{/zF^ j>K&RGI==bHJ)1Lio LJkޝDʉgHrD@@@@tt[vC;Tv Cڗ/la+7衑ݘzTVIV$@@%0&?> eVꛚ7v"0)*zύCefQ `/gtrs{ mƐJyOoVMvaDϴHtຩJ=wLJiJC>w6^{<:屎N8LLX䇑ҕ%%NoIJy|!ݕeV٣~.ꝿ-;ߨ?F sج @ IN~d@$`̭ ݞPZxdEU#G2t3)Ԕ{㗪]>jW>O[;aC>ާPWu֝bzN }ξ$ Yͽ S{!~c}ƭS r+mg!jB@@@@\bfoKs}iT'mFc4zhdHK2[+vvuiM/9 B@Zcn.mm9%fLz`ڴE>RۚKP~c竖w< n}aDlՕCrݲc3}]O[|-iN(ZgK׎\!V{ [ǧJ,Wp:pPb-vL%e&~ߟ|I3lD'Vݼ0V&1=̽Kas[W/ntlSq@ ${m@d^$e^*PuI7h7swV {p HްpĴY92$HY Tu 45d0sSfY(fDjK_F{P k[[;?G,l{/T5mV|@!`|FӣnenW NIQ!Jf|dZ}_<`nG=MNʡbVݭe˘s]ւ@S+"-l[{KWou6pؽټ\iȘ.3gΞ=;ѽu fRV MME[!3ewI-3BBXzM]^K۹=0+RZHP ƒc`2\QpNZbUD#26{?VF=42F+" ֳf戍'ˈڹh^cEɶ݇ƨᨏ"+}{فħ/_^a60<}-1i쀠oنGpi" 2A@@@CvkPIg|Lo[2Z%Ahͻf{_k0zsJWxp3ܔ)߲02 !fى mkyNyRA2P_TFA  2"l:vQJ^|.&~e(Ei,h%:c4zhd(\eTŞ9K^+K)ohD-uyLڼT^AEeNJ؝ _-aHܽ|PNmz'QWu5jNn]]ǥ_iɇ_ꩩFU{V%9xi}Beee\":SmgЗ9 SYv_Q۶d>ɩ_jwnWU2l.9n&MFZ^0YQ_TѦʎLz9p0L݉ Q @@@@ijхۊfט>V6C#u^/**^Ñ[Wur$e  - , قdsS,l;M| $_?&d[XIa>;tf.v>>HGn-3IΧ\;^̪c6uE~I ljJr? d} SVYuca. 9Y:#5B1N2     &PĔ*G͝)U)|1=424 |anļOjޞa)4ZAAle%1ÞZםHZR$ugHL?<q>AY->TW0EGd Cve,lKL1}Zߒ.L񖙋E!qww,/e۔X;/^3C#Ckl]ۧW{VVVLiQ֞ I2a@Z - Z        `"*        2 2;Z       f  BLp+VXAT@ 2ZCJJQYiA)IENDB`diskscan-0.21/progressbar/include/000077500000000000000000000000001456470715000172205ustar00rootroot00000000000000diskscan-0.21/progressbar/include/progressbar.h000066400000000000000000000064311456470715000217260ustar00rootroot00000000000000/** * \file * \author Trevor Fountain * \author Johannes Buchner * \author Erik Garrison * \date 2010-2014 * \copyright BSD 3-Clause * * progressbar -- a C class (by convention) for displaying progress * on the command line (to stderr). */ #ifndef PROGRESSBAR_H #define PROGRESSBAR_H #include #include #include #include /** * Progressbar data structure (do not modify or create directly) */ typedef struct _progressbar_t { /// maximum value unsigned long max; /// current value unsigned long value; /// time progressbar was started time_t start; /// label const char *label; /// characters for the beginning, filling and end of the /// progressbar. E.g. |### | has |#| struct { char begin; char fill; char end; } format; } progressbar; /// Create a new progressbar with the specified label and number of steps. /// /// @param label The label that will prefix the progressbar. /// @param max The number of times the progressbar must be incremented before it is considered complete, /// or, in other words, the number of tasks that this progressbar is tracking. /// /// @return A progressbar configured with the provided arguments. Note that the user is responsible for disposing /// of the progressbar via progressbar_finish when finished with the object. progressbar *progressbar_new(const char *label, unsigned long max); /// Create a new progressbar with the specified label, number of steps, and format string. /// /// @param label The label that will prefix the progressbar. /// @param max The number of times the progressbar must be incremented before it is considered complete, /// or, in other words, the number of tasks that this progressbar is tracking. /// @param format The format of the progressbar. The string provided must be three characters, and it will /// be interpretted with the first character as the left border of the bar, the second /// character of the bar and the third character as the right border of the bar. For example, /// "<->" would result in a bar formatted like "<------ >". /// /// @return A progressbar configured with the provided arguments. Note that the user is responsible for disposing /// of the progressbar via progressbar_finish when finished with the object. progressbar *progressbar_new_with_format(const char *label, unsigned long max, const char *format); /// Free an existing progress bar. Don't call this directly; call *progressbar_finish* instead. void progressbar_free(progressbar *bar); /// Increment the given progressbar. Don't increment past the initialized # of steps, though. void progressbar_inc(progressbar *bar); /// Set the current status on the given progressbar. void progressbar_update(progressbar *bar, unsigned long value); /// Set the label of the progressbar. Note that no rendering is done. The label is simply set so that the next /// rendering will use the new label. To immediately see the new label, call progressbar_draw. /// Does not update display or copy the label void progressbar_update_label(progressbar *bar, const char *label); /// Finalize (and free!) a progressbar. Call this when you're done, or if you break out /// partway through. void progressbar_finish(progressbar *bar); #endif diskscan-0.21/progressbar/include/statusbar.h000066400000000000000000000024621456470715000214050ustar00rootroot00000000000000/** * \file * \author Trevor Fountain * \author Johannes Buchner * \author Erik Garrison * \date 2010-2014 * \copyright BSD 3-Clause * * statusbar -- a C class (by convention) for displaying indefinite progress * on the command line (to stderr). */ #ifndef STATUSBAR_H #define STATUSBAR_H #include #include #include #include /** * Statusbar data structure (do not modify or create directly) */ typedef struct _statusbar_t { unsigned int start_time; const char *label; int format_index; int format_length; char *format; int last_printed; } statusbar; /// Create a new statusbar with the specified label and format string statusbar *statusbar_new_with_format(const char *label, const char *format); /// Create a new statusbar with the specified label statusbar *statusbar_new(const char *label); /// Free an existing progress bar. Don't call this directly; call *statusbar_finish* instead. void statusbar_free(statusbar *bar); /// Increment the given statusbar. void statusbar_inc(statusbar *bar); /// Finalize (and free!) a statusbar. Call this when you're done. void statusbar_finish(statusbar *bar); /// Draw a statusbar to the screen. Don't call this directly, /// as it's called internally by *statusbar_inc*. void statusbar_draw(statusbar *bar); #endif diskscan-0.21/progressbar/lib/000077500000000000000000000000001456470715000163435ustar00rootroot00000000000000diskscan-0.21/progressbar/lib/progressbar.c000066400000000000000000000144301456470715000210420ustar00rootroot00000000000000/** * \file * \author Trevor Fountain * \author Johannes Buchner * \author Erik Garrison * \date 2010-2014 * \copyright BSD 3-Clause * * progressbar -- a C class (by convention) for displaying progress * on the command line (to stderr). */ #include /* tgetent, tgetnum */ #include #include #include "progressbar.h" /// How wide we assume the screen is if termcap fails. enum { DEFAULT_SCREEN_WIDTH = 80 }; /// The smallest that the bar can ever be (not including borders) enum { MINIMUM_BAR_WIDTH = 10 }; /// The format in which the estimated remaining time will be reported static const char *const ETA_FORMAT = "ETA:%2dh%02dm%02ds"; /// The maximum number of characters that the ETA_FORMAT can ever yield enum { ETA_FORMAT_LENGTH = 13 }; /// Amount of screen width taken up by whitespace (i.e. whitespace between label/bar/ETA components) enum { WHITESPACE_LENGTH = 2 }; /// The amount of width taken up by the border of the bar component. enum { BAR_BORDER_WIDTH = 2 }; /// Models a duration of time broken into hour/minute/second components. The number of seconds should be less than the /// number of seconds in one minute, and the number of minutes should be less than the number of minutes in one hour. typedef struct { int hours; int minutes; int seconds; } progressbar_time_components; static void progressbar_draw(const progressbar *bar); /** * Create a new progress bar with the specified label, max number of steps, and format string. * Note that `format` must be exactly three characters long, e.g. "<->" to render a progress * bar like "<---------->". Returns NULL if there isn't enough memory to allocate a progressbar */ progressbar *progressbar_new_with_format(const char *label, unsigned long max, const char *format) { progressbar *new = malloc(sizeof(progressbar)); if(new == NULL) { return NULL; } new->max = max; new->value = 0; new->start = time(NULL); assert(3 == strlen(format) && "format must be 3 characters in length"); new->format.begin = format[0]; new->format.fill = format[1]; new->format.end = format[2]; progressbar_update_label(new, label); progressbar_draw(new); return new; } /** * Create a new progress bar with the specified label and max number of steps. */ progressbar *progressbar_new(const char *label, unsigned long max) { return progressbar_new_with_format(label, max, "|=|"); } void progressbar_update_label(progressbar *bar, const char *label) { bar->label = label; } /** * Delete an existing progress bar. */ void progressbar_free(progressbar *bar) { free(bar); } /** * Increment an existing progressbar by `value` steps. */ void progressbar_update(progressbar *bar, unsigned long value) { bar->value = value; progressbar_draw(bar); } /** * Increment an existing progressbar by a single step. */ void progressbar_inc(progressbar *bar) { progressbar_update(bar, bar->value+1); } static void progressbar_write_char(FILE *file, const int ch, const size_t times) { size_t i; for (i = 0; i < times; ++i) { fputc(ch, file); } } static int progressbar_max(int x, int y) { return x > y ? x : y; } static unsigned int get_screen_width(void) { char termbuf[2048]; if (tgetent(termbuf, getenv("TERM")) >= 0) { return tgetnum("co") /* -2 */; } else { return DEFAULT_SCREEN_WIDTH; } } static int progressbar_bar_width(int screen_width, int label_length) { return progressbar_max(MINIMUM_BAR_WIDTH, screen_width - label_length - ETA_FORMAT_LENGTH - WHITESPACE_LENGTH); } static int progressbar_label_width(int screen_width, int label_length, int bar_width) { int eta_width = ETA_FORMAT_LENGTH; // If the progressbar is too wide to fit on the screen, we must sacrifice the label. if (label_length + 1 + bar_width + 1 + ETA_FORMAT_LENGTH > screen_width) { return progressbar_max(0, screen_width - bar_width - eta_width - WHITESPACE_LENGTH); } else { return label_length; } } static int progressbar_remaining_seconds(const progressbar* bar) { double offset = difftime(time(NULL), bar->start); if (bar->value > 0 && offset > 0) { return (offset / (double) bar->value) * (bar->max - bar->value); } else { return 0; } } static progressbar_time_components progressbar_calc_time_components(int seconds) { int hours = seconds / 3600; seconds -= hours * 3600; int minutes = seconds / 60; seconds -= minutes * 60; progressbar_time_components components = {hours, minutes, seconds}; return components; } static void progressbar_draw(const progressbar *bar) { int screen_width = get_screen_width(); int label_length = strlen(bar->label); int bar_width = progressbar_bar_width(screen_width, label_length); int label_width = progressbar_label_width(screen_width, label_length, bar_width); int progressbar_completed = (bar->value >= bar->max); int bar_piece_count = bar_width - BAR_BORDER_WIDTH; int bar_piece_current = (progressbar_completed) ? bar_piece_count : bar_piece_count * ((double) bar->value / bar->max); progressbar_time_components eta = (progressbar_completed) ? progressbar_calc_time_components(difftime(time(NULL), bar->start)) : progressbar_calc_time_components(progressbar_remaining_seconds(bar)); if (label_width == 0) { // The label would usually have a trailing space, but in the case that we don't print // a label, the bar can use that space instead. bar_width += 1; } else { // Draw the label fwrite(bar->label, 1, label_width, stderr); fputc(' ', stderr); } // Draw the progressbar fputc(bar->format.begin, stderr); progressbar_write_char(stderr, bar->format.fill, bar_piece_current); progressbar_write_char(stderr, ' ', bar_piece_count - bar_piece_current); fputc(bar->format.end, stderr); // Draw the ETA fputc(' ', stderr); fprintf(stderr, ETA_FORMAT, eta.hours, eta.minutes, eta.seconds); fputc('\r', stderr); } /** * Finish a progressbar, indicating 100% completion, and free it. */ void progressbar_finish(progressbar *bar) { // Make sure we fill the progressbar so things look complete. progressbar_draw(bar); // Print a newline, so that future outputs to stderr look prettier fprintf(stderr, "\n"); // We've finished with this progressbar, so go ahead and free it. progressbar_free(bar); } diskscan-0.21/progressbar/lib/statusbar.c000066400000000000000000000046501456470715000205240ustar00rootroot00000000000000/** * \file * \author Trevor Fountain * \author Johannes Buchner * \author Erik Garrison * \date 2010-2014 * \copyright BSD 3-Clause * * statusbar -- a C class (by convention) for displaying progress * on the command line (to stderr). */ #include "statusbar.h" statusbar *statusbar_new_with_format(const char *label, const char *format) { statusbar *new = malloc(sizeof(statusbar)); new->label = label; new->start_time = time(0); new->format_length = strlen(format); new->format = malloc( sizeof(char) * (new->format_length + 1) ); strncpy(new->format, format, new->format_length); new->format_index = 0; new->last_printed = 0; return new; } statusbar *statusbar_new(const char *label) { return statusbar_new_with_format(label, "-\\|/"); } void statusbar_free(statusbar *bar) { // We malloc'd a string, so let's be sure to free it... free(bar->format); // ...before we free the struct itself. free(bar); return; } void statusbar_inc(statusbar *bar) { bar->format_index++; if (bar->format_index >= bar->format_length) { bar->format_index = 0; } statusbar_draw(bar); return; } void statusbar_draw(statusbar *bar) { // Erase the last draw. If anything else has been printed to stderr, // things are going to look mighty interesting... for(int i=0; i < bar->last_printed; i++) { fprintf(stderr,"\b"); } fprintf( stderr, "%s: %c%n", bar->label, bar->format[bar->format_index], &(bar->last_printed) ); return; } void statusbar_finish(statusbar *bar) { // Draw one more time, with the actual time to completion. unsigned int offset = time(0) - (bar->start_time); // Convert the time to display into HHH:MM:SS unsigned int h = offset/3600; offset -= h*3600; unsigned int m = offset/60; offset -= m*60; unsigned int s = offset; // Erase the last draw for(int i=0; i < bar->last_printed; i++) { fprintf(stderr,"\b"); } // Calculate number of spaces for right-justified time to completion fprintf(stderr,"%s: %3d:%02d:%02d%n",bar->label,h,m,s,&(bar->last_printed)); for(int i=0; i < bar->last_printed; i++) { fprintf(stderr,"\b"); } // Print right-justified fprintf(stderr,"%s: ",bar->label); for(int i=0; i < (80 - (bar->last_printed)); i++) { fprintf(stderr," "); } fprintf(stderr,"%3d:%02d:%02d\n",h,m,s); // We've finished with this statusbar, so go ahead and free it. statusbar_free(bar); return; } diskscan-0.21/progressbar/package.json000066400000000000000000000005611456470715000200650ustar00rootroot00000000000000{ "name": "progressbar", "version": "0.1.0", "repo": "doches/progressbar", "description": "A C library for displaying command-line progress bars", "keywords": ["terminal", "tty", "progress", "progressbar", "statusbar", "console"], "license": "BSD", "src": ["include/progressbar.h", "include/progressbar.c", "include/statusbar.h", "include/statusbar.c"] } diskscan-0.21/progressbar/test/000077500000000000000000000000001456470715000165545ustar00rootroot00000000000000diskscan-0.21/progressbar/test/demo.c000066400000000000000000000047361456470715000176560ustar00rootroot00000000000000/** * \file * \mainpage Progressbar and Statusbar -- Continuous console status updates * * \section Progressbar * Creating and starting the progress bar: \ref progressbar_new * * Updating the current progress: \ref progressbar_update, \ref progressbar_inc, \ref progressbar_update_label * * Finishing the progressbar (on success or failure): \ref progressbar_finish * * \section Statusbar * * Creating and starting the status bar: \ref statusbar_new * * Updating the current progress: \ref statusbar_inc * * Finishing the progressbar (on success or failure): \ref statusbar_finish * * \section Example Example Code * See \ref main in progressbar_demo.c * * Download the code from the repository at https://github.com/JohannesBuchner/progressbar * * \author Trevor Fountain * \author Johannes Buchner * \author Erik Garrison * \date 2010-2014 * \copyright BSD 3-Clause * * **/ #include "progressbar.h" #include "statusbar.h" #include #define SLEEP_US 100000 /** *Example for statusbar and progressbar usage **/ int main(void) { // Progress bar int max = 60; progressbar *smooth = progressbar_new("Smooth",max); for(int i=0; i < max; i++) { usleep(SLEEP_US); progressbar_inc(smooth); } progressbar_finish(smooth); progressbar *longlabel = progressbar_new("Three Second Task with a long label",3); for(int i=0; i < 3; i++) { progressbar_inc(longlabel); sleep(1); } progressbar_finish(longlabel); progressbar *fast = progressbar_new("Fast",20); for(int i=0; i < 20; i++) { usleep(SLEEP_US); progressbar_inc(fast); } progressbar_finish(fast); progressbar *custom = progressbar_new_with_format("Custom",max,"<.>"); for(int i=0; i < max; i++) { usleep(SLEEP_US); progressbar_inc(custom); } progressbar_finish(custom); // Status bar statusbar *status = statusbar_new("Indeterminate"); for(int i=0; i < 30; i++) { usleep(SLEEP_US); statusbar_inc(status); } statusbar_finish(status); statusbar *longStatus = statusbar_new("Status bar with a really long label"); for(int i=0; i < 10; i++) { usleep(SLEEP_US); statusbar_inc(longStatus); } statusbar_finish(longStatus); statusbar *customStatus = statusbar_new_with_format("Custom","(|)|"); for(int i=0; i < 30; i++) { usleep(SLEEP_US); statusbar_inc(customStatus); } statusbar_finish(customStatus); }