File manager - Edit - /home/ferretapmx/public_html/vdo.tar
Back
_etc_vdoconf.yml.lock 0000644 00000000000 15231106661 0010635 0 ustar 00 examples/monitor/monitor_check_vdostats_physicalSpace.pl 0000755 00000012010 15231203325 0020022 0 ustar 00 #!/usr/bin/perl ## # Copyright (c) 2018 Red Hat, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # monitor_check_vdostats_physicalSpace.pl [--warning <warn_pct>|-w <warn_pct>] # [--critical <crit_pct>|-c <crit_pct>] # <deviceName> # # This script parses the output of "vdostats --verbose" for a given VDO # volume, processes the "used percent" value, and returns a status code, # and a single-line output with status information. # # Options: # # -c <warn_pct>: critical threshold equal to or greater than # <warn_pct> percent. # # -w <crit_pct>: warning threshold equal to or greater than # <crit_pct> percent. # # The "vdostats" program must be in the path used by "sudo". # # $Id: //eng/vdo-releases/magnesium/src/tools/monitor/monitor_check_vdostats_physicalSpace.pl#1 $ # ## use strict; use warnings FATAL => qw(all); use Getopt::Long; # Constants for the service status return values. use constant { MONITOR_SERVICE_OK => 0, MONITOR_SERVICE_WARNING => 1, MONITOR_SERVICE_CRITICAL => 2, MONITOR_SERVICE_UNKNOWN => 3, }; my $inputWarnThreshold = -1; my $inputCritThreshold = -1; GetOptions("critical=i" => \$inputCritThreshold, "warning=i" => \$inputWarnThreshold); # Default warning and critical thresholds for "used percent". my $warnThreshold = 75; my $critThreshold = 90; if ($inputWarnThreshold >= 0 && $inputWarnThreshold <= 100) { $warnThreshold = $inputWarnThreshold; } if ($inputCritThreshold >= 0 && $inputCritThreshold <= 100) { $critThreshold = $inputCritThreshold; } # A hash to hold the statistics names and values gathered from input. my %stats = (); # Vital statistics for general VDO health. This array contains only the # names of the desired statistics to store in the %stats hash. my @statNames = ( 'operating mode', 'data blocks used', 'overhead blocks used', 'physical blocks', 'logical blocks', 'used percent', 'saving percent', '1k-blocks available', ); ############################################################################# # Get the statistics output for the given VDO device name, and filter the # desired stats values. ## sub getStats { if (!$ARGV[0]) { return; } my $deviceName = $ARGV[0]; my @verboseStatsOutput = `sudo vdostats $deviceName --verbose`; foreach my $statLabel (@statNames) { foreach my $inpline (@verboseStatsOutput) { if ($inpline =~ $statLabel) { $inpline =~ /.*: (.*)$/; my $statValue = $1; $stats{$statLabel} = $statValue; } } } } ############################################################################# # Print the vital statistics to stdout. ## sub printVitalStats { printf("operating mode: %s," . " physical used: %s%%," . " savings: %s%%.\n", $stats{"operating mode"}, $stats{"used percent"}, $stats{"saving percent"}); } ############################################################################# # main ## if (scalar(@ARGV) != 1) { print("Usage: monitor_check_vdostats_physicalSpace.pl\n"); print(" [--warning |-w VALUE]\n"); print(" [--critical|-c VALUE]\n"); print(" <deviceName>\n"); exit(MONITOR_SERVICE_UNKNOWN); } getStats(); # If the stats table is empty, nothing was found; return unknown status. # Otherwise, print the stats. if (!%stats) { printf("Unable to load vdostats verbose output.\n"); exit(MONITOR_SERVICE_UNKNOWN); } else { printVitalStats(\%stats); } # If the VDO is in read-only mode or recovering, exit now with a critical # status. if ($stats{"operating mode"} =~ "read-only") { exit(MONITOR_SERVICE_CRITICAL); } if ($stats{"operating mode"} =~ "recovering") { exit(MONITOR_SERVICE_WARNING); } if ($stats{"used percent"} =~ "N/A") { exit(MONITOR_SERVICE_UNKNOWN) } # Process the critical and warning thresholds. # If critThreshold is less than warnThreshold, the only used percentage # return codes will be "OK" or "CRITICAL". if ($stats{"used percent"} >= $warnThreshold && $stats{"used percent"} < $critThreshold) { exit(MONITOR_SERVICE_WARNING); } if ($stats{"used percent"} >= $critThreshold) { exit(MONITOR_SERVICE_CRITICAL); } if ($stats{"used percent"} >= 0 && $stats{"used percent"} < $warnThreshold) { exit(MONITOR_SERVICE_OK); } # Default exit condition. exit(MONITOR_SERVICE_UNKNOWN); examples/monitor/monitor_check_vdostats_logicalSpace.pl 0000755 00000011106 15231203325 0017625 0 ustar 00 #!/usr/bin/perl ## # Copyright (c) 2018 Red Hat, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # monitor_check_vdostats_logicalSpace.pl [--warning <warn_pct>|-w <warn_pct>] # [--critical <crit_pct>|-c <crit_pct>] # <deviceName> # # This script parses the output of "vdostats --verbose" for a given VDO # volume, processes the "used percent" value, and returns a status code, # and a single-line output with status information. # # Options: # # -c <warn_pct>: critical threshold equal to or greater than # <warn_pct> percent. # # -w <crit_pct>: warning threshold equal to or greater than # <crit_pct> percent. # # The "vdostats" program must be in the path used by "sudo". # # $Id: //eng/vdo-releases/magnesium/src/tools/monitor/monitor_check_vdostats_logicalSpace.pl#1 $ # ## use strict; use warnings FATAL => qw(all); use Getopt::Long; # Constants for the service status return values. use constant { MONITOR_SERVICE_OK => 0, MONITOR_SERVICE_WARNING => 1, MONITOR_SERVICE_CRITICAL => 2, MONITOR_SERVICE_UNKNOWN => 3, }; my $inputWarnThreshold = -1; my $inputCritThreshold = -1; GetOptions("critical=i" => \$inputCritThreshold, "warning=i" => \$inputWarnThreshold); # Default warning and critical thresholds for "logical used percent". my $warnThreshold = 80; my $critThreshold = 95; if ($inputWarnThreshold >= 0 && $inputWarnThreshold <= 100) { $warnThreshold = $inputWarnThreshold; } if ($inputCritThreshold >= 0 && $inputCritThreshold <= 100) { $critThreshold = $inputCritThreshold; } # A hash to hold the statistics names and values gathered from input. my %stats = (); # Vital statistics for general VDO health. This array contains only the # names of the desired statistics to store in the %stats hash. my @statNames = ( 'operating mode', 'data blocks used', 'overhead blocks used', 'logical blocks used', 'physical blocks', 'logical blocks', 'used percent', 'saving percent', '1k-blocks available', ); ############################################################################# # Get the statistics output for the given VDO device name, and filter the # desired stats values. ## sub getStats { if (!$ARGV[0]) { return; } my $deviceName = $ARGV[0]; my @verboseStatsOutput = `sudo vdostats $deviceName --verbose`; foreach my $statLabel (@statNames) { foreach my $inpline (@verboseStatsOutput) { if ($inpline =~ $statLabel) { $inpline =~ /.*: (.*)$/; my $statValue = $1; $stats{$statLabel} = $statValue; } } } } ############################################################################# # main ## if (scalar(@ARGV) != 1) { print("Usage: monitor_check_vdostats_logicalSpace.pl\n"); print(" [--warning |-w VALUE]\n"); print(" [--critical|-c VALUE]\n"); print(" <deviceName>\n"); exit(MONITOR_SERVICE_UNKNOWN); } getStats(); # If the stats table is empty, nothing was found; return unknown status. # Otherwise, print the stats. if (!%stats) { printf("Unable to load vdostats verbose output.\n"); exit(MONITOR_SERVICE_UNKNOWN); } # Calculate logical percent used, and print the value. my $logicalUsedPercent = (100 * $stats{"logical blocks used"} / $stats{"logical blocks"}); printf("logical used: %.2f%%\n", $logicalUsedPercent); # Process the critical and warning thresholds. # If critThreshold is less than warnThreshold, the only used percentage # return codes will be "OK" or "CRITICAL". if ($logicalUsedPercent >= $warnThreshold && $logicalUsedPercent < $critThreshold) { exit(MONITOR_SERVICE_WARNING); } if ($logicalUsedPercent >= $critThreshold) { exit(MONITOR_SERVICE_CRITICAL); } if ($logicalUsedPercent >= 0 && $logicalUsedPercent < $warnThreshold) { exit(MONITOR_SERVICE_OK); } # Default exit condition. exit(MONITOR_SERVICE_UNKNOWN); examples/monitor/monitor_check_vdostats_savingPercent.pl 0000755 00000011115 15231203325 0020047 0 ustar 00 #!/usr/bin/perl ## # Copyright (c) 2018 Red Hat, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # # monitor_check_vdostats_savingPercent.pl [--warning <warn_pct>|-w <warn_pct>] # [--critical <crit_pct>|-c <crit_pct>] # <deviceName> # # This script parses the output of "vdostats --verbose" for a given VDO # volume, processes the "used percent" value, and returns a status code, # and a single-line output with status information. # # Options: # # -c <warn_pct>: critical threshold equal to or greater than # <warn_pct> percent. # # -w <crit_pct>: warning threshold equal to or greater than # <crit_pct> percent. # # The "vdostats" program must be in the path used by "sudo". # # $Id: //eng/vdo-releases/magnesium/src/tools/monitor/monitor_check_vdostats_savingPercent.pl#1 $ # ## use strict; use warnings FATAL => qw(all); use Getopt::Long; # Constants for the service status return values. use constant { MONITOR_SERVICE_OK => 0, MONITOR_SERVICE_WARNING => 1, MONITOR_SERVICE_CRITICAL => 2, MONITOR_SERVICE_UNKNOWN => 3, }; my $inputWarnThreshold = -1; my $inputCritThreshold = -1; GetOptions("critical=i" => \$inputCritThreshold, "warning=i" => \$inputWarnThreshold); # Default warning and critical thresholds for "logical used percent". my $warnThreshold = 50; my $critThreshold = 5; if ($inputWarnThreshold >= 0 && $inputWarnThreshold <= 100) { $warnThreshold = $inputWarnThreshold; } if ($inputCritThreshold >= 0 && $inputCritThreshold <= 100) { $critThreshold = $inputCritThreshold; } # A hash to hold the statistics names and values gathered from input. my %stats = (); # Vital statistics for general VDO health. This array contains only the # names of the desired statistics to store in the %stats hash. my @statNames = ( 'operating mode', 'data blocks used', 'overhead blocks used', 'logical blocks used', 'physical blocks', 'logical blocks', 'used percent', 'saving percent', '1k-blocks available', ); ############################################################################# # Get the statistics output for the given VDO device name, and filter the # desired stats values. ## sub getStats { if (!$ARGV[0]) { return; } my $deviceName = $ARGV[0]; my @verboseStatsOutput = `sudo vdostats $deviceName --verbose`; foreach my $statLabel (@statNames) { foreach my $inpline (@verboseStatsOutput) { if ($inpline =~ $statLabel) { $inpline =~ /.*: (.*)$/; my $statValue = $1; $stats{$statLabel} = $statValue; } } } } ############################################################################# # main ## if (scalar(@ARGV) != 1) { print("Usage: monitor_check_vdostats_savingPercent.pl\n"); print(" [--warning |-w VALUE]\n"); print(" [--critical|-c VALUE]\n"); print(" <deviceName>\n"); exit(MONITOR_SERVICE_UNKNOWN); } getStats(); # If the stats table is empty, nothing was found; return unknown status. # Otherwise, print the stats. if (!%stats) { printf("Unable to load vdostats verbose output.\n"); exit(MONITOR_SERVICE_UNKNOWN); } printf("saving percent: %s%%\n", $stats{"saving percent"}); # Process the critical and warning thresholds. # If critThreshold is less than warnThreshold, the only used percentage # return codes will be "OK" or "CRITICAL". # An empty VDO volume has a saving percent of "N/A" when 0 logical blocks # are used. This is interpreted as an "OK" status. if ($stats{"saving percent"} =~ "N/A") { exit(MONITOR_SERVICE_OK); } if ($stats{"saving percent"} <= $warnThreshold && $stats{"saving percent"} > $critThreshold) { exit(MONITOR_SERVICE_WARNING); } if ($stats{"saving percent"} <= $critThreshold) { exit(MONITOR_SERVICE_CRITICAL); } if ($stats{"saving percent"} > $warnThreshold) { exit(MONITOR_SERVICE_OK); } # Default exit condition. exit(MONITOR_SERVICE_UNKNOWN); examples/systemd/VDO.mount.example 0000644 00000000445 15231203325 0013217 0 ustar 00 [Unit] Description = Mount filesystem that lives on VDO name = VDO.mount Requires = vdo.service systemd-remount-fs.service After = multi-user.target Conflicts = umount.target [Mount] What = /dev/mapper/my_vdo Where = /VDO Type = xfs Options = discard [Install] WantedBy = multi-user.target examples/ansible/test_vdocreate_alloptions.yml 0000644 00000001123 15231203325 0015772 0 ustar 00 - hosts: vdoClients remote_user: username become: yes become_method: sudo connection: ssh gather_facts: yes tasks: - name: Create VDO volume vdo1 vdo: name: vdo1 state: present compression: enabled deduplication: enabled device: /dev/blockdevice logicalsize: 1T blockmapcachesize: 21G readcache: enabled readcachesize: 64M writepolicy: async emulate512: enabled slabsize: 16G indexmem: 0.5 ackthreads: 2 biothreads: 4 cputhreads: 6 logicalthreads: 6 physicalthreads: 2 examples/ansible/test_vdoremove.yml 0000644 00000000316 15231203325 0013563 0 ustar 00 - hosts: vdoClients remote_user: username become: yes become_method: sudo connection: ssh gather_facts: yes tasks: - name: Remove VDO volume vdo1 vdo: name: vdo1 state: absent examples/ansible/README.txt 0000644 00000001470 15231203325 0011473 0 ustar 00 This directory contains example playbooks for the "vdo" module in Ansible, which can be used to create and remove VDO volumes, modify configuration options, and start and stop VDO volumes. The Ansible "vdo" module can be found in Ansible, version 2.5 or greater. General information on Ansible can be found at http://docs.ansible.com/ To run a playbook: 1. On the control system, set up a passwordless SSH session via the "ssh-agent bash" and "ssh-add" commands. 2. Specify the managed hosts and groups by adding them to the /etc/ansible/hosts file on the control system. 3. Using the "hosts" value, construct a playbook detailing the desired state of the VDO volume. 4. When ready, execute "ansible-playbook <playbook.yml>". For additional diagnostic output, run "ansible-playbook <playbook.yml> -vvvv". examples/ansible/test_vdocreate.yml 0000644 00000000404 15231203325 0013527 0 ustar 00 - hosts: vdoClients remote_user: username become: yes become_method: sudo connection: ssh gather_facts: yes tasks: - name: Create VDO volume vdo1 vdo: name: vdo1 state: present device: /dev/blockdevice logicalsize: 1T COPYING 0000644 00000035502 15231203325 0005600 0 ustar 00 GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. usr/bin/vdo 0000755 00000141300 15231455275 0006653 0 ustar 00 #!/usr/bin/python # # Copyright (c) 2018 Red Hat, Inc. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License # as published by the Free Software Foundation; either version 2 # of the License, or (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA # 02110-1301, USA. # """ vdo - VDO management utility $Id: //eng/vdo-releases/magnesium/src/python/vdo/vdo#19 $ """ #pylint: disable=C0302 from __future__ import print_function import argparse import copy import gettext import logging import locale import os import re import sys from textwrap import TextWrapper import traceback # Temporary patch to address layout changes for dir in sys.path: vdoDir = os.path.join(dir, 'vdo') if os.path.isdir(vdoDir): sys.path.append(vdoDir) break from utils import Command, Logger from vdomgmnt import * gettext.install('vdo') ######################################################################## # "Line too long" #pylint: disable=C0301 class VdoArgumentParser(argparse.ArgumentParser): """Argument parser for the vdo command. Attributes: lvmOptionalSuffix (str): describes usage of lvm suffixes lvmOptionalSiSuffix (str): describes usage of lvm SI suffixes """ lvmOptionalSuffix = _("""Using a value with a {options} or {last} suffix is optional""").format(options = ", ".join([Constants.lvmSuffixTextMap[suffix] for suffix in Constants.lvmSuffixes[:-1]]), last = Constants.lvmSuffixTextMap[ Constants.lvmSuffixes[-1]]) lvmOptionalSiSuffix = _("""Using a value with a {options} or {last} suffix is optional""").format(options = ", ".join([Constants.lvmSiSuffixTextMap[suffix] for suffix in Constants.lvmSiSuffixes[:-1]]), last = Constants.lvmSiSuffixTextMap[ Constants.lvmSiSuffixes[-1]]) #################################################################### class CommandArgumentParser(argparse.ArgumentParser): """Argument parser type to use for commands. Provides command-identifying "unrecognized arguments" error rather than having the unrecognized arguments bubble up to the root parser and result in a non-specific "unrecognized arguments" error. """ ################################################################## def __init__(self, *args, **kwargs): super(VdoArgumentParser.CommandArgumentParser, self).__init__(*args, **kwargs) self._redirected = False ################################################################## def parse_known_args(self, args = None, namespace = None): """Redirects the command's argument parsing through parse_arg() which will, if there are unknown arguments, result in a cmmand-specific "unrecognized arguments" message. """ result = None if not self._redirected: self._redirected = True namespace = self.parse_args(args, namespace) self._redirected = False result = (namespace, []) else: result = super(VdoArgumentParser.CommandArgumentParser, self).parse_known_args(args, namespace) return result #################################################################### # Public methods #################################################################### #################################################################### # Overridden methods #################################################################### def parse_args(self, args = None, namespace = None): namespace = super(VdoArgumentParser, self).parse_args(args, namespace) self.__postParseChecks(namespace) return namespace #################################################################### def __init__(self, *args, **kwargs): if kwargs.get("description") is None: kwargs["description"] = _(""" Manage kernel VDO devices and related configuration information. For help on individual commands specify the command followed by --help. Unless otherwise noted all commands must be run with root privileges. """) super(VdoArgumentParser, self).__init__(*args, **kwargs) subparserAdder = self.add_subparsers( title = "management commands", help = "description", dest = "command", metavar = "command", parser_class = VdoArgumentParser.CommandArgumentParser) self.__commonOptions = self._commonOptionsParser() self.__namingOptions = self._namingOptionsParser() # activate command. highLevelHelp = _(""" Activates one or more VDO volumes. Activated volumes can be started using the 'start' command. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._activateCommandParser = subparserAdder.add_parser( "activate", parents = [self.__namingOptions, self.__commonOptions], help = highLevelHelp, description = description) # changeWritePolicy command. highLevelHelp = _(""" Modifies the write policy of one or all running VDO volumes. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._changeWritePolicyCommandParser = subparserAdder.add_parser( "changeWritePolicy", parents = [self.__namingOptions, self._writePolicyOptionParser(required = True), self.__commonOptions], help = highLevelHelp, description = description) # create command. highLevelHelp = _(""" Creates a VDO volume and its associated index and makes it available. """) description = _(""" {0} If --activate={1} is specified the VDO volume is created but not made available. Will not overwrite an existing file system or formatted VDO volume unless --force is given. This command must be run with root privileges. """).format(highLevelHelp, Constants.disabled) self._createCommandParser = subparserAdder.add_parser( "create", parents = [self._nameOptionParser(), self._deviceOptionParser(), self._activateOptionParser(), self._blockMapCacheSizeOptionParser(), self._blockMapPeriodOptionParser(), self._compressionOptionParser(), self._deduplicationOptionParser(), self._emulate512OptionParser(), self._forceOptionParser(), self._indexMemOptionParser(), self._readCacheOptionParser(), self._readCacheSizeOptionParser(), self._sparseIndexOptionParser(), self._vdoAckThreadsOptionParser(), self._vdoBioRotationIntervalOptionParser(), self._vdoBioThreadsOptionParser(), self._vdoCpuThreadsOptionParser(), self._vdoHashZoneThreadsOptionParser(), self._vdoLogicalSizeOptionParser(), self._vdoLogicalThreadsOptionParser(), self._vdoLogLevelOptionParser(), self._vdoPhysicalThreadsOptionParser(), self._vdoSlabSizeOptionParser(), self._writePolicyOptionParser(), self.__commonOptions], help = highLevelHelp, description = description) # deactivate command. highLevelHelp = _(""" Deactivates one or more VDO volumes. Deactivated volumes cannot be started by the 'start' command. Deactivating a currently running volume does not stop it. """) description = _(""" {0} Once stopped a deactivated VDO volume must be activated before it can be started again. This command must be run with root privileges. """).format(highLevelHelp) self._deactivateCommandParser = subparserAdder.add_parser( "deactivate", parents = [self.__namingOptions, self.__commonOptions], help = highLevelHelp, description = description) # disableCompression command. highLevelHelp = _(""" Disables compression on one or more VDO volumes. If the VDO volume is running, takes effect immediately. """) description = _(""" {0} If the VDO volume is not running compression will be disabled the next time the VDO volume is started. This command must be run with root privileges. """).format(highLevelHelp) self._disableCompressionCommandParser = subparserAdder.add_parser( "disableCompression", parents = [self.__namingOptions, self.__commonOptions], help = highLevelHelp, description = description) # disableDeduplication command. highLevelHelp = _(""" Disables deduplication on one more VDO volumes. If the VDO volume is running, takes effect immediately. """) description = _(""" {0} If the VDO volume is not running deduplication will be disabled the next time the VDO volume is started. This command must be run with root privileges. """).format(highLevelHelp) self._disableDeduplicationCommandParser = subparserAdder.add_parser( "disableDeduplication", parents = [self.__namingOptions, self.__commonOptions], help = highLevelHelp, description = description) # enableCompression command. highLevelHelp = _(""" Enables compression on one or more VDO volumes. If the VDO volume is running, takes effect immediately. """) description = _(""" {0} If the VDO volume is not running compression will be enabled the next time the VDO volume is started. This command must be run with root privileges. """).format(highLevelHelp) self._enableCompressionCommandParser = subparserAdder.add_parser( "enableCompression", parents = [self.__namingOptions, self.__commonOptions], help = highLevelHelp, description = description) # enableDeduplication command. highLevelHelp = _(""" Enables deduplication on one or more VDO volumes. If the VDO volume is running, takes effect immediately. """) description = _(""" {0} If the VDO volume is not running deduplication will be enabled the next time the VDO volume is started. This command must be run with root privileges. """).format(highLevelHelp) self._enableDeduplicationCommandParser = subparserAdder.add_parser( "enableDeduplication", parents = [self.__namingOptions, self.__commonOptions], help = highLevelHelp, description = description) # growLogical command. highLevelHelp = _(""" Grows the logical size of a VDO volume. The volume must exist and must be running. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._growLogicalCommandParser = subparserAdder.add_parser( "growLogical", parents = [self._nameOptionParser(), self._vdoLogicalSizeOptionParser(required = True), self.__commonOptions], help = highLevelHelp, description = description) # growPhysical command. highLevelHelp = _(""" Grows the physical size of a VDO volume. The volume must exist and must be running. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._growPhysicalCommandParser = subparserAdder.add_parser( "growPhysical", parents = [self._nameOptionParser(), self.__commonOptions], help = highLevelHelp, description = description) # list command. highLevelHelp = _(""" Displays a list of started VDO volumes. If --all is specified it displays both started and non-started volumes. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._listCommandParser = subparserAdder.add_parser( "list", parents = [self._allOptionParser(), self.__commonOptions], help = highLevelHelp, description = description) # modify command. highLevelHelp = _(""" Modifies configuration parameters of one or all VDO volumes. Changes take effect the next time the VDO device is started; already-running devices are not affected. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._changeableModifyOptions = ["blockMapCacheSize", "blockMapPeriod", "readCache", "readCacheSize", "vdoAckThreads", "vdoBioRotationInterval", "vdoBioThreads", "vdoCpuThreads", "vdoHashZoneThreads", "vdoLogicalThreads", "vdoPhysicalThreads"] self._modifyCommandParser = subparserAdder.add_parser( "modify", parents = [self.__namingOptions, self._blockMapCacheSizeOptionParser(noDefault = True), self._blockMapPeriodOptionParser(noDefault = True), self._readCacheOptionParser(noDefault = True), self._readCacheSizeOptionParser(noDefault = True), self._vdoAckThreadsOptionParser(noDefault = True), self._vdoBioRotationIntervalOptionParser(noDefault = True), self._vdoBioThreadsOptionParser(noDefault = True), self._vdoCpuThreadsOptionParser(noDefault = True), self._vdoHashZoneThreadsOptionParser(noDefault = True), self._vdoLogicalThreadsOptionParser(noDefault = True), self._vdoPhysicalThreadsOptionParser(noDefault = True), self.__commonOptions], help = highLevelHelp, description = description) # printConfigFile command. highLevelHelp = _(""" Prints the configuration file to stdout. This command does not require root privileges. """) description = _(""" {0} """).format(highLevelHelp) self._printConfigFileCommandParser = subparserAdder.add_parser( "printConfigFile", parents = [self.__commonOptions], help = highLevelHelp, description = description) # remove command. commandText = _(""" """) highLevelHelp = _(""" Removes one or more stopped VDO volumes and associated indexes. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._removeCommandParser = subparserAdder.add_parser( "remove", parents = [self.__namingOptions, self._forceOptionParser(), self.__commonOptions], help = highLevelHelp, description = description) # start command. highLevelHelp = _(""" Starts one or more stopped, activated VDO volumes and associated services. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._startCommandParser = subparserAdder.add_parser( "start", parents = [self.__namingOptions, self._forceRebuildOptionParser(), self.__commonOptions], help = highLevelHelp, description = description) # status command. highLevelHelp = _(""" Reports VDO system and volume status in YAML format. This command does not require root privileges though information will be incomplete if run without. """) description = _(""" {0} """).format(highLevelHelp) self._statusCommandParser = subparserAdder.add_parser( "status", parents = [self._namingOptionsParser(required = False), self.__commonOptions], help = highLevelHelp, description = description) # stop command. commandText = _(""" """) highLevelHelp = _(""" Stops one or more running VDO volumes and associated services. """) description = _(""" {0} This command must be run with root privileges. """).format(highLevelHelp) self._stopCommandParser = subparserAdder.add_parser( "stop", parents = [self.__namingOptions, self._forceOptionParser(), self.__commonOptions], help = highLevelHelp, description = description) #################################################################### # Protected methods #################################################################### def _activateOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--activate", choices = Constants.enableChoices, help = _(""" Indicates if the VDO volume should, in addition to being created, be activated and started. The default is {activate}. """) .format(activate = Defaults.activate)) return parser #################################################################### def _allOptionParser(self): parser = argparse.ArgumentParser(add_help = False) self.__parserAddAllOption(parser) return parser #################################################################### def _blockMapCacheSizeOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else _("The default is {0}.").format(Defaults.blockMapCacheSize)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--blockMapCacheSize", type = self.__optionCheck(Defaults.checkPageCachesz), metavar = "<megabytes>", help = _(""" Specifies the amount of memory allocated for caching block map pages; the value must be a multiple of {pageSize}. {suffixOptions}. If no suffix is supplied, the value will be interpreted as {defaultUnits}. The value must be at least {minCacheSize} and less than {maxCachePlusOne}. Note that there is a memory overhead of 15%%. {defaultHelp} """) .format(pageSize = Defaults.vdoPhysicalBlockSize, suffixOptions = self.lvmOptionalSiSuffix, defaultUnits = Constants.lvmDefaultUnitsText, minCacheSize = Defaults.blockMapCacheSizeMin, maxCachePlusOne = Defaults.blockMapCacheSizeMaxPlusOne, defaultHelp = defaultHelp)) return parser #################################################################### def _blockMapPeriodOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else _("The default value is {0}.") .format(Defaults.blockMapPeriod)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--blockMapPeriod", type = self.__optionCheck( Defaults.checkBlockMapPeriod), metavar = "<period>", help = _(""" Tunes the quantity of block map updates that can accumulate before cache pages are flushed to disk. The value must at least {minPeriod} and less than or equal to {maxPeriod}. A lower value means shorter recovery time but lower performance. {defaultHelp} """) .format(minPeriod = Defaults.blockMapPeriodMin, maxPeriod = Defaults.blockMapPeriodMax, defaultHelp = defaultHelp)) return parser #################################################################### def _commonOptionsParser(self): return argparse.ArgumentParser(add_help = False, parents = [self._confFileOptionParser(), self._debugOptionParser(), self._logFileOptionParser(), self._verboseOptionParser()]) #################################################################### def _compressionOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--compression", choices = Constants.enableChoices, default = Defaults.compression, help = _(""" Enables or disables compression when creating a VDO volume. The default is {compression}. Compression may be disabled if necessary to maximize performance or to speed processing of data that is unlikely to compress. """) .format(compression = Defaults.compression)) return parser #################################################################### def _confFileOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("-f", "--confFile", type = self.__optionCheck(Defaults.checkConfFile), default = Defaults.confFile, metavar = "<file>", help = _(""" Specifies an alternate configuration file; the default is {file}. """) .format(file = Defaults.confFile)) return parser #################################################################### def _debugOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("-d", "--debug", action = "store_true", dest = "debug", help = argparse.SUPPRESS) return parser #################################################################### def _deduplicationOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--deduplication", choices = Constants.enableChoices, default = Defaults.deduplication, help = _(""" Enables or disables deduplication when creating a VDO volume. The default is {deduplication}. Deduplication may be disabled in instances where data is not expected to have good deduplication rates but compression is still desired. """) .format(deduplication = Defaults.deduplication)) return parser #################################################################### def _deviceOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--device", type = self.__optionCheck(Defaults.checkBlkDev), metavar = "<devicepath>", required = True, help = _(""" Specifies the absolute path of the device to use for VDO storage. """)) return parser #################################################################### def _emulate512OptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--emulate512", choices = Constants.enableChoices, help = _(""" Specifies that the VDO volume is to emulate a 512 byte block device. The default is {emulate512}. """) .format(emulate512 = Defaults.emulate512)) return parser #################################################################### def _forceOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--force", action = "store_true", dest = "force", help = _(""" When creating a volume, ignores any existing file system or VDO signature already present in the storage device. When stopping or removing a VDO volume, first unmounts the file system stored on the device if mounted. """)) return parser #################################################################### def _forceRebuildOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--forceRebuild", action = "store_true", dest = "forceRebuild", help = _(""" Forces an offline rebuild of a read-only VDO's metadata before starting so that it may be brought back online and made available. This option may result in data loss or corruption. """)) return parser #################################################################### def _indexMemOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--indexMem", type = self.__optionCheck(Defaults.checkIndexmem), default = Defaults.indexMem, metavar = "<gigabytes>", help = _(""" Specifies the amount of index memory in gigabytes; the default is currently {indexMem} GB. The special decimal values 0.25, 0.5, 0.75 can be used, as can any integer value at least {min} and less than or equal to {max}. (The special deciml values are matched as exact strings; "0.5" works but "0.50" is not accepted.) Larger values will require more disk space. For a dense index, each gigabyte of index memory will use approximately 11 GB of storage. For a sparse index, each gigabyte of index memory will use approximately 100 GB of storage. """) .format(indexMem = Defaults.indexMem, min = Defaults.indexMemIntMin, max = Defaults.indexMemIntMax, )) return parser #################################################################### def _logFileOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--logfile", type = self.__optionCheck(Defaults.checkLogFile), metavar = "<pathname>", help = _(""" Specify the path of the file to which log messages are directed. If unspecified, log messages will go to syslog. Warning and error messages are always logged to syslog. """)) return parser #################################################################### def _nameOptionParser(self): parser = argparse.ArgumentParser(add_help = False) self.__parserAddNameOption(parser, required = True) return parser #################################################################### def _namingOptionsParser(self, required = True): """ Arguments: required (boolean) - if True, an argument is required to this parser """ parser = argparse.ArgumentParser( add_help = False).add_mutually_exclusive_group( required = required) self.__parserAddAllOption(parser) self.__parserAddNameOption(parser) return parser #################################################################### def _readCacheOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else _("The default is {0}.").format(Defaults.readCache)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--readCache", choices = Constants.enableChoices, help = _(""" Enables or disables the read cache within the VDO device. The cache should be enabled if write workloads are expected to have high levels of deduplication, or for read intensive workloads of highly compressible data. {defaultHelp} """) .format(defaultHelp = defaultHelp)) return parser #################################################################### def _readCacheSizeOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else _("The default is {0}.").format(Defaults.readCacheSize)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--readCacheSize", type = self.__optionCheck(Defaults.checkReadCachesz), metavar = "<megabytes>", help = _(""" Specifies the extra VDO device read cache size in {defaultUnits}. This space is in addition to a system-defined minimum. {suffixOptions}. The value must be at least {minCacheSize} and less than {maxCachePlusOne}. {threadMem} MB of memory will be used per MB of read cache specified, per bio thread. {defaultHelp} """) .format(defaultUnits = Constants.lvmDefaultUnitsText, suffixOptions = self.lvmOptionalSiSuffix, minCacheSize = Defaults.readCacheSizeMin, maxCachePlusOne = Defaults.readCacheSizeMaxPlusOne, threadMem = Defaults.bioThreadReadCacheOverheadMB, defaultHelp = defaultHelp)) return parser #################################################################### def _sparseIndexOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--sparseIndex", choices = Constants.enableChoices, help = _(""" Enables sparse indexing. The default is {sparseIndex}. """) .format(sparseIndex = Defaults.sparseIndex)) return parser #################################################################### def _vdoAckThreadsOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else "The default is {0}.".format(Defaults.ackThreads)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoAckThreads", type = self.__optionCheck( Defaults.checkThreadCount0_100), metavar = "<threadCount>", help = _(""" Specifies the number of threads to use for acknowledging completion of requested VDO I/O operations. The value must be at least {min} and less than or equal to {max}. {defaultHelp} """) .format(min = Defaults.ackThreadsMin, max = Defaults.ackThreadsMax, defaultHelp = defaultHelp)) return parser #################################################################### def _vdoBioRotationIntervalOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else "The default is {0}.".format(Defaults.bioRotationInterval)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoBioRotationInterval", type = self.__optionCheck( Defaults.checkRotationInterval), metavar = "<ioCount>", help = _(""" Specifies the number of I/O operations to enqueue for each bio-submission thread before directing work to the next. The value must be at least {min} and less than or equal to {max}. {defaultHelp} """) .format(min = Defaults.bioRotationIntervalMin, max = Defaults.bioRotationIntervalMax, defaultHelp = defaultHelp)) return parser #################################################################### def _vdoBioThreadsOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else _("The default is {0}.").format(Defaults.bioThreads)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoBioThreads", type = self.__optionCheck( Defaults.checkThreadCount1_100), metavar = "<threadCount>", help = _(""" Specifies the number of threads to use for submitting I/O operations to the storage device. The value must be at least {min} and less than or equal to {max}. Each additional thread after the first will use an additional {threadOverhead} MB of RAM, plus {readCacheOverhead} MB of RAM per megabyte of configured read cache size. {defaultHelp} """) .format(min = Defaults.bioThreadsMin, max = Defaults.bioThreadsMax, threadOverhead = Defaults.bioThreadOverheadMB, readCacheOverhead = Defaults.bioThreadReadCacheOverheadMB, defaultHelp = defaultHelp)) return parser #################################################################### def _vdoCpuThreadsOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else _("The default is {0}.").format(Defaults.cpuThreads)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoCpuThreads", type = self.__optionCheck( Defaults.checkThreadCount1_100), metavar = "<threadCount>", help = _(""" Specifies the number of threads to use for CPU-intensive work such as hashing or compression. The value must be at least {min} and less than or equal to {max}. {defaultHelp} """) .format(min = Defaults.cpuThreadsMin, max = Defaults.cpuThreadsMax, defaultHelp = defaultHelp)) return parser #################################################################### def _vdoHashZoneThreadsOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else "The default is {0}.".format(Defaults.hashZoneThreads)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoHashZoneThreads", type = self.__optionCheck( Defaults.checkThreadCount0_100), metavar = "<threadCount>", help = _(""" Specifies the number of threads across which to subdivide parts of the VDO processing based on the hash value computed from the block data. The value must be at least {min} and less than or equal to {max}. vdoHashZonesThreads, vdoLogicalThreads and vdoPhysicalThreads must be either all zero or all non-zero. {defaultHelp} """) .format(min = Defaults.hashZoneThreadsMin, max = Defaults.hashZoneThreadsMax, defaultHelp = defaultHelp)) return parser #################################################################### def _vdoLogicalThreadsOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else "The default is {0}.".format(Defaults.hashZoneThreads)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoLogicalThreads", type = self.__optionCheck( Defaults.checkThreadCount0_100), metavar = "<threadCount>", help = _(""" Specifies the number of threads across which to subdivide parts of the VDO processing based on the hash value computed from the block data. The value must be at least {min} and less than or equal to {max}. A logical thread count of {threshold} or more will require explicitly specifying a sufficiently large block map cache size, as well. vdoHashZonesThreads, vdoLogicalThreads and vdoPhysicalThreads must be either all zero or all non-zero. {defaultHelp} """) .format(min = Defaults.logicalThreadsMin, max = Defaults.logicalThreadsMax, threshold = Defaults.logicalThreadsBlockMapCacheSizeThreshold, defaultHelp = defaultHelp)) return parser #################################################################### def _vdoLogicalSizeOptionParser(self, required = False): """ Arguments: required (boolean) - if True, no default is provided nor mentioned in the help text """ defaultHelp = ("" if required else _("The default is the size of the storage device.")) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoLogicalSize", type = self.__optionCheck(Defaults.checkLogicalSize), default = None if required else "0", required = required, metavar = "<megabytes>", help = _(""" Specifies the logical VDO volume size in {defaultUnits}. {suffixOptions}. Used for over-provisioning volumes. The maximum size supported is {max}. {defaultHelp} """) .format(defaultUnits = Constants.lvmDefaultUnitsText, suffixOptions = self.lvmOptionalSuffix, max = Defaults.logicalSizeMax, defaultHelp = defaultHelp)) return parser #################################################################### def _vdoLogLevelOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoLogLevel", choices = Defaults.vdoLogLevelChoices, default = Defaults.vdoLogLevel, help = _(""" Specifies the VDO driver log level. Levels are case-sensitive. The default is {logLevel}. """) .format(logLevel = Defaults.vdoLogLevel)) return parser #################################################################### def _vdoPhysicalThreadsOptionParser(self, noDefault = False): """ Arguments: noDefault (boolean) - if True, no default is mentioned in the help text """ defaultHelp = ("" if noDefault else _("The default is {0}.").format(Defaults.physicalThreads)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoPhysicalThreads", type = self.__optionCheck( Defaults.checkPhysicalThreadCount), metavar = "<threadCount>", help = _(""" Specifies the number of threads across which to subdivide parts of the VDO processing based on physical block addresses. The value must be at least {min} and less than or equal to {max}. Each additional thread after the first will use an additional {overhead} MB of RAM. vdoPhysicalThreads, vdoHashZonesThreads and vdoLogicalThreads must be either all zero or all non-zero. {defaultHelp} """) .format(min = Defaults.physicalThreadsMin, max = Defaults.physicalThreadsMax, overhead = Defaults.physicalThreadOverheadMB, defaultHelp = defaultHelp)) return parser #################################################################### def _vdoSlabSizeOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--vdoSlabSize", type = self.__optionCheck(Defaults.checkSlabSize), default = Defaults.slabSize, metavar = "<megabytes>", help = _(""" Specifies the size of the increment by which a VDO is grown. Using a smaller size constrains the total maximum physical size that can be accommodated. Must be a power of two between {minSize} and {maxSize}; the default is {defaultSlabSize}. {suffixOptions}. If no suffix is used, the value will be interpreted as {defaultUnits}. """) .format(minSize = Defaults.slabSizeMin, maxSize = Defaults.slabSizeMax, defaultSlabSize = Defaults.slabSize, suffixOptions = self.lvmOptionalSuffix, defaultUnits = Constants.lvmDefaultUnitsText)) return parser #################################################################### def _verboseOptionParser(self): parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--verbose", action = "store_true", dest = "verbose", help = _(""" Prints commands before executing them. """)) return parser #################################################################### def _writePolicyOptionParser(self, required = False): """ Arguments: required (boolean) - if True, no default is provided nor mentioned in the help """ defaultHelp = ("" if required else _("The default is {0}.").format(Defaults.writePolicy)) parser = argparse.ArgumentParser(add_help = False) parser.add_argument("--writePolicy", choices = Defaults.writePolicyChoices, default = None if required else Defaults.writePolicy, required = required, help = _(""" Specifies the write policy. 'sync' means writes are acknowledged only after data is on stable storage. 'sync' policy is not supported if the underlying storage is not also synchronous. 'async' means that writes are acknowledged when data has been cached for writing to stable storage; data which has not been flushed is not guaranteed to persist in this mode. 'auto' means that VDO will check the storage device and determine whether it supports flushes. If it does, VDO will run in async mode, otherwise it will run in sync mode. {defaultHelp} """) .format(defaultHelp = defaultHelp)) return parser #################################################################### # Private methods #################################################################### @classmethod def __optionCheck(cls, checkFunc): """Returns a callable for option checking which traps and translates exceptions from the vdo management option checking to argparse's exception in order to provide consistent behavior for option errors including preventing stack traces. Arguments: checkFunc (callable) - the vdo management option check method to use Returns: __checker (callable) - the wrapper which translates vdo option check exception to argparse's. """ def __checker(optionValue): try: optionValue = checkFunc(optionValue) except ArgumentError as ex: raise argparse.ArgumentTypeError(str(ex)) return optionValue return __checker #################################################################### def __parserAddAllOption(self, parser): parser.add_argument("-a", "--all", action = "store_true", dest = "all", help = _(""" Indicates that the command should be applied to all configured VDO volumes. May not be used with --name. """)) #################################################################### def __parserAddNameOption(self, parser, required = False): parser.add_argument("-n", "--name", type = self.__optionCheck(Defaults.checkVDOName), metavar = "<volume>", required = required, help = _(""" Operates on the specified VDO volume. May not be used with --all. """)) #################################################################### def __postParseChecks(self, namespace): """Performs post-parsing checks between linked options. If there is a check failure invokes the appropriate parser error() method to display the error message and exit. Arguments: namespace (Namespace) - the Namespace instance populated by parsing arguments """ # For modify check that there was at least one option specified. if namespace.command == "modify": options = [option for option in self._changeableModifyOptions if getattr(namespace, option, None) is not None] if len(options) == 0: self._modifyCommandParser.error( _("options must be specified from: {0}") .format("--{0}" .format(", --".join(self._changeableModifyOptions)))) ######################################################################## def main(): """The main program. Exit codes: 0 SUCCESS success 1 ERROR error(s) occurred """ SUCCESS = 0 ERROR = 1 try: import vdoInstrumentation except ImportError: pass try: locale.setlocale(locale.LC_ALL, '') except locale.Error: pass arguments = VdoArgumentParser().parse_args() Logger.configure(os.path.basename(sys.argv[0]), arguments.logfile, arguments.debug) mainLogger = Logger.getLogger(Logger.myname) mainLogger.info(' '.join(['running'] + sys.argv)) Command.setDefaults(arguments.verbose) operation = None exitval = ERROR try: operation = vdoOperations[arguments.command] except KeyError: mainLogger.error(_('Unknown command "{0}"'.format(arguments.command))) try: if operation is not None: operation.run(arguments) exitval = SUCCESS except Exception as ex: if isinstance(ex, ExitStatus): # pylint: disable=E1101 # If it's an instance of ExitStatus we know it has exitStatus. exitval = ex.exitStatus traceInfo = sys.exc_info()[2] mainLogger.error(str(ex)) # By default (i.e., without --debug) this will log to the # specified log file, if any, but not to stderr, because of the # priority thresholds we set for the different logging # destinations. We can't use mainLogger.exception because that # logs at level ERROR which would go everywhere. traceText = 'Traceback:\n' + ''.join(traceback.format_tb(traceInfo)) mainLogger.info(traceText.rstrip()) logging.shutdown() sys.exit(exitval) ######################################################################## if __name__ == "__main__": main()
| ver. 1.4 |
Github
|
.
| PHP 8.2.32 | Generation time: 0.07 |
proxy
|
phpinfo
|
Settings