1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +03:00
lvm2/tools/lvmcmdline.c

3704 lines
98 KiB
C
Raw Normal View History

2004-03-26 15:00:24 +03:00
/*
2008-01-30 17:00:02 +03:00
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
* Copyright (C) 2004-2012 Red Hat, Inc. All rights reserved.
2004-05-05 01:25:57 +04:00
*
2004-03-30 23:35:44 +04:00
* This file is part of LVM2.
*
* This copyrighted material is made available to anyone wishing to use,
* modify, copy, or redistribute it subject to the terms and conditions
* of the GNU Lesser General Public License v.2.1.
2004-03-30 23:35:44 +04:00
*
* You should have received a copy of the GNU Lesser General Public License
2004-03-30 23:35:44 +04:00
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2004-03-26 15:00:24 +03:00
*/
#include "tools.h"
2004-03-26 15:00:24 +03:00
#include "lvm2cmdline.h"
#include "lib/label/label.h"
device usage based on devices file The LVM devices file lists devices that lvm can use. The default file is /etc/lvm/devices/system.devices, and the lvmdevices(8) command is used to add or remove device entries. If the file does not exist, or if lvm.conf includes use_devicesfile=0, then lvm will not use a devices file. When the devices file is in use, the regex filter is not used, and the filter settings in lvm.conf or on the command line are ignored. LVM records devices in the devices file using hardware-specific IDs, such as the WWID, and attempts to use subsystem-specific IDs for virtual device types. These device IDs are also written in the VG metadata. When no hardware or virtual ID is available, lvm falls back using the unstable device name as the device ID. When devnames are used, lvm performs extra scanning to find devices if their devname changes, e.g. after reboot. When proper device IDs are used, an lvm command will not look at devices outside the devices file, but when devnames are used as a fallback, lvm will scan devices outside the devices file to locate PVs on renamed devices. A config setting search_for_devnames can be used to control the scanning for renamed devname entries. Related to the devices file, the new command option --devices <devnames> allows a list of devices to be specified for the command to use, overriding the devices file. The listed devices act as a sort of devices file in terms of limiting which devices lvm will see and use. Devices that are not listed will appear to be missing to the lvm command. Multiple devices files can be kept in /etc/lvm/devices, which allows lvm to be used with different sets of devices, e.g. system devices do not need to be exposed to a specific application, and the application can use lvm on its own set of devices that are not exposed to the system. The option --devicesfile <filename> is used to select the devices file to use with the command. Without the option set, the default system devices file is used. Setting --devicesfile "" causes lvm to not use a devices file. An existing, empty devices file means lvm will see no devices. The new command vgimportdevices adds PVs from a VG to the devices file and updates the VG metadata to include the device IDs. vgimportdevices -a will import all VGs into the system devices file. LVM commands run by dmeventd not use a devices file by default, and will look at all devices on the system. A devices file can be created for dmeventd (/etc/lvm/devices/dmeventd.devices) If this file exists, lvm commands run by dmeventd will use it. Internal implementaion: - device_ids_read - read the devices file . add struct dev_use (du) to cmd->use_devices for each devices file entry - dev_cache_scan - get /dev entries . add struct device (dev) to dev_cache for each device on the system - device_ids_match - match devices file entries to /dev entries . match each du on cmd->use_devices to a dev in dev_cache, using device ID . on match, set du->dev, dev->id, dev->flags MATCHED_USE_ID - label_scan - read lvm headers and metadata from devices . filters are applied, those that do not need data from the device . filter-deviceid skips devs without MATCHED_USE_ID, i.e. skips /dev entries that are not listed in the devices file . read lvm label from dev . filters are applied, those that use data from the device . read lvm metadata from dev . add info/vginfo structs for PVs/VGs (info is "lvmcache") - device_ids_find_renamed_devs - handle devices with unstable devname ID where devname changed . this step only needed when devs do not have proper device IDs, and their dev names change, e.g. after reboot sdb becomes sdc. . detect incorrect match because PVID in the devices file entry does not match the PVID found when the device was read above . undo incorrect match between du and dev above . search system devices for new location of PVID . update devices file with new devnames for PVIDs on renamed devices . label_scan the renamed devs - continue with command processing
2020-06-23 21:25:41 +03:00
#include "lib/device/device_id.h"
#include "lvm-version.h"
#include "lib/locking/lvmlockd.h"
device usage based on devices file The LVM devices file lists devices that lvm can use. The default file is /etc/lvm/devices/system.devices, and the lvmdevices(8) command is used to add or remove device entries. If the file does not exist, or if lvm.conf includes use_devicesfile=0, then lvm will not use a devices file. When the devices file is in use, the regex filter is not used, and the filter settings in lvm.conf or on the command line are ignored. LVM records devices in the devices file using hardware-specific IDs, such as the WWID, and attempts to use subsystem-specific IDs for virtual device types. These device IDs are also written in the VG metadata. When no hardware or virtual ID is available, lvm falls back using the unstable device name as the device ID. When devnames are used, lvm performs extra scanning to find devices if their devname changes, e.g. after reboot. When proper device IDs are used, an lvm command will not look at devices outside the devices file, but when devnames are used as a fallback, lvm will scan devices outside the devices file to locate PVs on renamed devices. A config setting search_for_devnames can be used to control the scanning for renamed devname entries. Related to the devices file, the new command option --devices <devnames> allows a list of devices to be specified for the command to use, overriding the devices file. The listed devices act as a sort of devices file in terms of limiting which devices lvm will see and use. Devices that are not listed will appear to be missing to the lvm command. Multiple devices files can be kept in /etc/lvm/devices, which allows lvm to be used with different sets of devices, e.g. system devices do not need to be exposed to a specific application, and the application can use lvm on its own set of devices that are not exposed to the system. The option --devicesfile <filename> is used to select the devices file to use with the command. Without the option set, the default system devices file is used. Setting --devicesfile "" causes lvm to not use a devices file. An existing, empty devices file means lvm will see no devices. The new command vgimportdevices adds PVs from a VG to the devices file and updates the VG metadata to include the device IDs. vgimportdevices -a will import all VGs into the system devices file. LVM commands run by dmeventd not use a devices file by default, and will look at all devices on the system. A devices file can be created for dmeventd (/etc/lvm/devices/dmeventd.devices) If this file exists, lvm commands run by dmeventd will use it. Internal implementaion: - device_ids_read - read the devices file . add struct dev_use (du) to cmd->use_devices for each devices file entry - dev_cache_scan - get /dev entries . add struct device (dev) to dev_cache for each device on the system - device_ids_match - match devices file entries to /dev entries . match each du on cmd->use_devices to a dev in dev_cache, using device ID . on match, set du->dev, dev->id, dev->flags MATCHED_USE_ID - label_scan - read lvm headers and metadata from devices . filters are applied, those that do not need data from the device . filter-deviceid skips devs without MATCHED_USE_ID, i.e. skips /dev entries that are not listed in the devices file . read lvm label from dev . filters are applied, those that use data from the device . read lvm metadata from dev . add info/vginfo structs for PVs/VGs (info is "lvmcache") - device_ids_find_renamed_devs - handle devices with unstable devname ID where devname changed . this step only needed when devs do not have proper device IDs, and their dev names change, e.g. after reboot sdb becomes sdc. . detect incorrect match because PVID in the devices file entry does not match the PVID found when the device was read above . undo incorrect match between du and dev above . search system devices for new location of PVID . update devices file with new devnames for PVIDs on renamed devices . label_scan the renamed devs - continue with command processing
2020-06-23 21:25:41 +03:00
#include "lib/datastruct/str_list.h"
#include "libdaemon/server/daemon-stray.h"
2004-03-26 15:00:24 +03:00
/* coverity[unnecessary_header] */
2004-03-26 15:00:24 +03:00
#include "stub.h"
#include "lib/misc/last-path-component.h"
2004-03-26 15:00:24 +03:00
#include <sys/stat.h>
#include <time.h>
#include <sys/resource.h>
#include <dirent.h>
#include <paths.h>
#include <locale.h>
#include <langinfo.h>
2004-03-26 15:00:24 +03:00
#ifdef HAVE_GETOPTLONG
# include <getopt.h>
# define GETOPTLONG_FN(a, b, c, d, e) getopt_long((a), (b), (c), (d), (e))
# define OPTIND_INIT 0
#else
struct option {
};
extern int optind;
extern char *optarg;
# define GETOPTLONG_FN(a, b, c, d, e) getopt((a), (b), (c))
# define OPTIND_INIT 1
#endif
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* Table of command names
*/
extern struct command_name command_names[];
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* Table of commands (as defined in command-lines.in)
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
*/
struct command commands[COMMAND_COUNT];
2024-04-28 21:14:42 +03:00
static struct command *commands_idx[COMMAND_COUNT];
static struct cmdline_context _cmdline;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* Table of command line functions
*
* This table could be auto-generated once all commands have been converted
* to use these functions instead of the old per-command-name function.
* For now, any command id not included here uses the old command fn.
*/
static const struct command_function _command_functions[CMD_COUNT] = {
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
{ lvmconfig_general_CMD, lvmconfig },
{ lvchange_properties_CMD, lvchange_properties_cmd },
{ lvchange_resync_CMD, lvchange_resync_cmd },
{ lvchange_syncaction_CMD, lvchange_syncaction_cmd },
{ lvchange_rebuild_CMD, lvchange_rebuild_cmd },
{ lvchange_activate_CMD, lvchange_activate_cmd },
{ lvchange_refresh_CMD, lvchange_refresh_cmd },
{ lvchange_monitor_CMD, lvchange_monitor_poll_cmd },
{ lvchange_poll_CMD, lvchange_monitor_poll_cmd },
{ lvchange_persistent_CMD, lvchange_persistent_cmd },
{ vgchange_locktype_CMD, vgchange_locktype_cmd },
{ vgchange_lockstart_CMD, vgchange_lock_start_stop_cmd },
{ vgchange_lockstop_CMD, vgchange_lock_start_stop_cmd },
{ vgchange_systemid_CMD, vgchange_systemid_cmd },
/* lvconvert utilities related to repair. */
{ lvconvert_repair_CMD, lvconvert_repair_cmd },
{ lvconvert_replace_pv_CMD, lvconvert_replace_pv_cmd },
/* lvconvert utilities related to snapshots. */
{ lvconvert_split_cow_snapshot_CMD, lvconvert_split_snapshot_cmd },
{ lvconvert_merge_snapshot_CMD, lvconvert_merge_snapshot_cmd },
{ lvconvert_combine_split_snapshot_CMD, lvconvert_combine_split_snapshot_cmd },
/* lvconvert utility to trigger polling on an LV. */
{ lvconvert_start_poll_CMD, lvconvert_start_poll_cmd },
{ lvconvert_plain_CMD, lvconvert_start_poll_cmd },
/* lvconvert utilities for creating/maintaining thin and cache objects. */
{ lvconvert_to_thinpool_CMD, lvconvert_to_pool_cmd },
{ lvconvert_to_cachepool_CMD, lvconvert_to_pool_cmd },
{ lvconvert_to_thin_with_external_CMD, lvconvert_to_thin_with_external_cmd },
{ lvconvert_to_thin_with_data_CMD, lvconvert_to_thin_with_data_cmd },
{ lvconvert_to_cache_with_cachevol_CMD, lvconvert_to_cache_with_cachevol_cmd },
2020-02-05 22:42:36 +03:00
{ lvconvert_to_cache_with_device_CMD, lvconvert_to_cache_with_cachevol_cmd },
{ lvconvert_to_cache_with_cachepool_CMD, lvconvert_to_cache_with_cachepool_cmd },
{ lvconvert_to_writecache_CMD, lvconvert_to_writecache_cmd },
2020-02-05 22:42:36 +03:00
{ lvconvert_to_writecache_with_device_CMD, lvconvert_to_writecache_cmd },
{ lvconvert_swap_pool_metadata_CMD, lvconvert_swap_pool_metadata_cmd },
{ lvconvert_to_thinpool_or_swap_metadata_CMD, lvconvert_to_pool_or_swap_metadata_cmd },
{ lvconvert_to_cachepool_or_swap_metadata_CMD, lvconvert_to_pool_or_swap_metadata_cmd },
{ lvconvert_merge_thin_CMD, lvconvert_merge_thin_cmd },
{ lvconvert_split_and_keep_cache_CMD, lvconvert_split_cache_cmd },
{ lvconvert_split_and_remove_cache_CMD, lvconvert_split_cache_cmd },
/* lvconvert raid-related type conversions */
{ lvconvert_raid_types_CMD, lvconvert_raid_types_cmd },
/* lvconvert utilities for raid/mirror */
{ lvconvert_split_mirror_images_CMD, lvconvert_split_mirror_images_cmd},
{ lvconvert_change_mirrorlog_CMD, lvconvert_change_mirrorlog_cmd },
{ lvconvert_merge_mirror_images_CMD, lvconvert_merge_mirror_images_cmd },
{ lvconvert_change_region_size_CMD, lvconvert_change_region_size_cmd },
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* redirected to merge_snapshot/merge_thin/merge_mirrors */
{ lvconvert_merge_CMD, lvconvert_merge_cmd },
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* lvconvert VDO pool */
{ lvconvert_to_vdopool_CMD, lvconvert_to_vdopool_cmd },
{ lvconvert_to_vdopool_param_CMD, lvconvert_to_vdopool_param_cmd },
Allow dm-integrity to be used for raid images dm-integrity stores checksums of the data written to an LV, and returns an error if data read from the LV does not match the previously saved checksum. When used on raid images, dm-raid will correct the error by reading the block from another image, and the device user sees no error. The integrity metadata (checksums) are stored on an internal LV allocated by lvm for each linear image. The internal LV is allocated on the same PV as the image. Create a raid LV with an integrity layer over each raid image (for raid levels 1,4,5,6,10): lvcreate --type raidN --raidintegrity y [options] Add an integrity layer to images of an existing raid LV: lvconvert --raidintegrity y LV Remove the integrity layer from images of a raid LV: lvconvert --raidintegrity n LV Settings Use --raidintegritymode journal|bitmap (journal is default) to configure the method used by dm-integrity to ensure crash consistency. Initialization When integrity is added to an LV, the kernel needs to initialize the integrity metadata/checksums for all blocks in the LV. The data corruption checking performed by dm-integrity will only operate on areas of the LV that are already initialized. The progress of integrity initialization is reported by the "syncpercent" LV reporting field (and under the Cpy%Sync lvs column.) Example: create a raid1 LV with integrity: $ lvcreate --type raid1 -m1 --raidintegrity y -n rr -L1G foo Creating integrity metadata LV rr_rimage_0_imeta with size 12.00 MiB. Logical volume "rr_rimage_0_imeta" created. Creating integrity metadata LV rr_rimage_1_imeta with size 12.00 MiB. Logical volume "rr_rimage_1_imeta" created. Logical volume "rr" created. $ lvs -a foo LV VG Attr LSize Origin Cpy%Sync rr foo rwi-a-r--- 1.00g 4.93 [rr_rimage_0] foo gwi-aor--- 1.00g [rr_rimage_0_iorig] 41.02 [rr_rimage_0_imeta] foo ewi-ao---- 12.00m [rr_rimage_0_iorig] foo -wi-ao---- 1.00g [rr_rimage_1] foo gwi-aor--- 1.00g [rr_rimage_1_iorig] 39.45 [rr_rimage_1_imeta] foo ewi-ao---- 12.00m [rr_rimage_1_iorig] foo -wi-ao---- 1.00g [rr_rmeta_0] foo ewi-aor--- 4.00m [rr_rmeta_1] foo ewi-aor--- 4.00m
2019-11-21 01:07:27 +03:00
/* lvconvert for integrity */
{ lvconvert_integrity_CMD, lvconvert_integrity_cmd },
lvcreate: new cache or writecache lv with single command To create a new cache or writecache LV with a single command: lvcreate --type cache|writecache -n Name -L Size --cachedevice PVfast VG [PVslow ...] - A new main linear|striped LV is created as usual, using the specified -n Name and -L Size, and using the optionally specified PVslow devices. - Then, a new cachevol LV is created internally, using PVfast specified by the cachedevice option. - Then, the cachevol is attached to the main LV, converting the main LV to type cache|writecache. Include --cachesize Size to specify the size of cache|writecache to create from the specified --cachedevice PVs, otherwise the entire cachedevice PV is used. The --cachedevice option can be repeated to create the cache from multiple devices, or the cachedevice option can contain a tag name specifying a set of PVs to allocate the cache from. To create a new cache or writecache LV with a single command using an existing cachevol LV: lvcreate --type cache|writecache -n Name -L Size --cachevol LVfast VG [PVslow ...] - A new main linear|striped LV is created as usual, using the specified -n Name and -L Size, and using the optionally specified PVslow devices. - Then, the cachevol LVfast is attached to the main LV, converting the main LV to type cache|writecache. In cases where more advanced types (for the main LV or cachevol LV) are needed, they should be created independently and then combined with lvconvert. Example ------- user creates a new VG with one slow device and one fast device: $ vgcreate vg /dev/slow1 /dev/fast1 user creates a new 8G main LV on /dev/slow1 that uses all of /dev/fast1 as a writecache: $ lvcreate --type writecache --cachedevice /dev/fast1 -n main -L 8G vg /dev/slow1 Example ------- user creates a new VG with two slow devs and two fast devs: $ vgcreate vg /dev/slow1 /dev/slow2 /dev/fast1 /dev/fast2 user creates a new 8G main LV on /dev/slow1 and /dev/slow2 that uses all of /dev/fast1 and /dev/fast2 as a writecache: $ lvcreate --type writecache --cachedevice /dev/fast1 --cachedevice /dev/fast2 -n main -L 8G vg /dev/slow1 /dev/slow2 Example ------- A user has several slow devices and several fast devices in their VG, the slow devs have tag @slow, the fast devs have tag @fast. user creates a new 8G main LV on the slow devs with a 2G writecache on the fast devs: $ lvcreate --type writecache -n main -L 8G --cachedevice @fast --cachesize 2G vg @slow
2020-04-10 21:17:37 +03:00
/* lvcreate */
{ lvcreate_and_attach_cachevol_for_cache_CMD, lvcreate_and_attach_cache_cmd },
{ lvcreate_and_attach_cachedevice_for_cache_CMD, lvcreate_and_attach_cache_cmd },
{ lvcreate_and_attach_cachevol_for_writecache_CMD, lvcreate_and_attach_writecache_cmd },
{ lvcreate_and_attach_cachedevice_for_writecache_CMD, lvcreate_and_attach_writecache_cmd },
{ pvscan_display_CMD, pvscan_display_cmd },
{ pvscan_cache_CMD, pvscan_cache_cmd },
/* lvextend/lvreduce/lvresize */
{ lvextend_policy_CMD, lvextend_policy_cmd },
{ lvextend_pool_metadata_CMD, lvresize_cmd },
{ lvresize_pool_metadata_CMD, lvresize_cmd },
{ lvextend_pv_CMD, lvresize_cmd },
{ lvresize_pv_CMD, lvresize_cmd },
{ lvextend_size_CMD, lvresize_cmd },
{ lvreduce_size_CMD, lvresize_cmd },
{ lvresize_size_CMD, lvresize_cmd },
};
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* Command line args */
int arg_is_valid_for_command(const struct cmd_context *cmd, int a)
{
int i;
for (i = 0; i < cmd->cname->num_args; i++) {
if (cmd->cname->valid_args[i] == a)
return 1;
}
return 0;
}
unsigned arg_count(const struct cmd_context *cmd, int a)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return cmd->opt_arg_values ? cmd->opt_arg_values[a].count : 0;
}
unsigned grouped_arg_count(const struct arg_values *av, int a)
{
return av ? av[a].count : 0;
}
unsigned arg_is_set(const struct cmd_context *cmd, int a)
{
return arg_count(cmd, a) ? 1 : 0;
}
int arg_from_list_is_set(const struct cmd_context *cmd, const char *err_found, ...)
{
int arg;
va_list ap;
va_start(ap, err_found);
while ((arg = va_arg(ap, int)) != -1 && !arg_is_set(cmd, arg))
/* empty */;
va_end(ap);
if (arg == -1)
return 0;
if (err_found)
log_error("%s %s.", arg_long_option_name(arg), err_found);
return 1;
}
int arg_outside_list_is_set(const struct cmd_context *cmd, const char *err_found, ...)
{
int i, arg;
va_list ap;
for (i = 0; i < ARG_COUNT; ++i) {
switch (i) {
/* skip common options */
case commandprofile_ARG:
case config_ARG:
case debug_ARG:
case driverloaded_ARG:
case help2_ARG:
case help_ARG:
case profile_ARG:
case quiet_ARG:
case verbose_ARG:
case version_ARG:
case yes_ARG:
continue;
}
if (!arg_is_set(cmd, i))
continue; /* unset */
va_start(ap, err_found);
while (((arg = va_arg(ap, int)) != -1) && (arg != i))
/* empty */;
va_end(ap);
if (arg == i)
continue; /* set and in list */
if (err_found)
log_error("Option %s %s.", arg_long_option_name(i), err_found);
return 1;
}
return 0;
}
int arg_from_list_is_negative(const struct cmd_context *cmd, const char *err_found, ...)
{
int arg, ret = 0;
va_list ap;
va_start(ap, err_found);
while ((arg = va_arg(ap, int)) != -1)
if (arg_sign_value(cmd, arg, SIGN_NONE) == SIGN_MINUS) {
if (err_found)
log_error("%s %s.", arg_long_option_name(arg), err_found);
ret = 1;
}
va_end(ap);
return ret;
}
int arg_from_list_is_zero(const struct cmd_context *cmd, const char *err_found, ...)
{
int arg, ret = 0;
va_list ap;
va_start(ap, err_found);
while ((arg = va_arg(ap, int)) != -1)
if (arg_is_set(cmd, arg) &&
!arg_int_value(cmd, arg, 0)) {
if (err_found)
log_error("%s %s.", arg_long_option_name(arg), err_found);
ret = 1;
}
va_end(ap);
return ret;
}
unsigned grouped_arg_is_set(const struct arg_values *av, int a)
{
return grouped_arg_count(av, a) ? 1 : 0;
}
const char *arg_long_option_name(int a)
{
return _cmdline.opt_names[a].long_opt;
}
2014-09-19 16:29:12 +04:00
const char *arg_value(const struct cmd_context *cmd, int a)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return cmd->opt_arg_values ? cmd->opt_arg_values[a].value : NULL;
}
2014-09-19 16:29:12 +04:00
const char *arg_str_value(const struct cmd_context *cmd, int a, const char *def)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].value : def;
}
const char *grouped_arg_str_value(const struct arg_values *av, int a, const char *def)
{
return grouped_arg_count(av, a) ? av[a].value : def;
}
int32_t grouped_arg_int_value(const struct arg_values *av, int a, const int32_t def)
{
return grouped_arg_count(av, a) ? av[a].i_value : def;
}
2014-09-19 16:29:12 +04:00
int32_t first_grouped_arg_int_value(const struct cmd_context *cmd, int a, const int32_t def)
{
struct arg_value_group_list *current_group;
struct arg_values *av;
2012-04-11 16:49:10 +04:00
dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
av = current_group->arg_values;
if (grouped_arg_count(av, a))
return grouped_arg_int_value(av, a, def);
}
return def;
}
2014-09-19 16:29:12 +04:00
int32_t arg_int_value(const struct cmd_context *cmd, int a, const int32_t def)
{
return (_cmdline.opt_names[a].flags & ARG_GROUPABLE) ?
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
first_grouped_arg_int_value(cmd, a, def) : (arg_is_set(cmd, a) ? cmd->opt_arg_values[a].i_value : def);
}
2014-09-19 16:29:12 +04:00
uint32_t arg_uint_value(const struct cmd_context *cmd, int a, const uint32_t def)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].ui_value : def;
}
2014-09-19 16:29:12 +04:00
int64_t arg_int64_value(const struct cmd_context *cmd, int a, const int64_t def)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].i64_value : def;
}
2014-09-19 16:29:12 +04:00
uint64_t arg_uint64_value(const struct cmd_context *cmd, int a, const uint64_t def)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].ui64_value : def;
}
/* No longer used.
const void *arg_ptr_value(struct cmd_context *cmd, int a, const void *def)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].ptr : def;
}
*/
2014-09-19 16:29:12 +04:00
sign_t arg_sign_value(const struct cmd_context *cmd, int a, const sign_t def)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].sign : def;
}
2014-09-19 16:29:12 +04:00
percent_type_t arg_percent_value(const struct cmd_context *cmd, int a, const percent_type_t def)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_is_set(cmd, a) ? cmd->opt_arg_values[a].percent : def;
}
int arg_count_increment(struct cmd_context *cmd, int a)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return cmd->opt_arg_values[a].count++;
}
int yes_no_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
2004-03-26 15:00:24 +03:00
{
av->sign = SIGN_NONE;
av->percent = PERCENT_NONE;
2004-03-26 15:00:24 +03:00
if (!strcmp(av->value, "y")) {
av->i_value = 1;
av->ui_value = 1;
2004-05-24 17:44:10 +04:00
}
else if (!strcmp(av->value, "n")) {
av->i_value = 0;
av->ui_value = 0;
2004-05-24 17:44:10 +04:00
}
else
return 0;
return 1;
}
int activation_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
2004-05-24 17:44:10 +04:00
{
av->sign = SIGN_NONE;
av->percent = PERCENT_NONE;
2004-05-24 17:44:10 +04:00
if (!strcmp(av->value, "e") || !strcmp(av->value, "ey") ||
!strcmp(av->value, "ye")) {
av->i_value = CHANGE_AEY;
av->ui_value = CHANGE_AEY;
2004-05-24 17:44:10 +04:00
}
else if (!strcmp(av->value, "s") || !strcmp(av->value, "sy") ||
!strcmp(av->value, "ys")) {
av->i_value = CHANGE_ASY;
av->ui_value = CHANGE_ASY;
}
else if (!strcmp(av->value, "y")) {
av->i_value = CHANGE_AY;
av->ui_value = CHANGE_AY;
2004-03-26 15:00:24 +03:00
}
else if (!strcmp(av->value, "a") || !strcmp(av->value, "ay") ||
!strcmp(av->value, "ya")) {
av->i_value = CHANGE_AAY;
av->ui_value = CHANGE_AAY;
}
else if (!strcmp(av->value, "n") || !strcmp(av->value, "en") ||
!strcmp(av->value, "ne")) {
av->i_value = CHANGE_AN;
av->ui_value = CHANGE_AN;
2004-06-16 21:13:41 +04:00
}
else if (!strcmp(av->value, "ln") || !strcmp(av->value, "nl")) {
av->i_value = CHANGE_ALN;
av->ui_value = CHANGE_ALN;
2004-06-16 21:13:41 +04:00
}
else if (!strcmp(av->value, "ly") || !strcmp(av->value, "yl")) {
av->i_value = CHANGE_ALY;
av->ui_value = CHANGE_ALY;
2004-03-26 15:00:24 +03:00
}
else
return 0;
return 1;
}
int cachemode_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
{
cache_mode_t mode;
if (!set_cache_mode(&mode, av->value))
return_0;
av->i_value = mode;
av->ui_value = mode;
return 1;
}
int cachemetadataformat_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcmp(av->value, "auto")) {
av->i_value = CACHE_METADATA_FORMAT_UNSELECTED;
av->ui_value = CACHE_METADATA_FORMAT_UNSELECTED;
} else if (!int_arg(cmd, av))
return_0;
switch (av->i_value) {
case CACHE_METADATA_FORMAT_UNSELECTED:
case CACHE_METADATA_FORMAT_1:
case CACHE_METADATA_FORMAT_2:
return 1;
}
log_error("Selected cache metadata format %d is not supported.", av->i_value);
return 0;
}
int discards_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
{
thin_discards_t discards;
2014-11-08 03:28:38 +03:00
if (!set_pool_discards(&discards, av->value))
return_0;
av->i_value = discards;
av->ui_value = discards;
return 1;
}
int mirrorlog_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
{
int log_count;
2014-11-08 03:28:38 +03:00
if (!set_mirror_log_count(&log_count, av->value))
return_0;
av->i_value = log_count;
av->ui_value = log_count;
return 1;
}
int metadatatype_arg(struct cmd_context *cmd, struct arg_values *av)
2004-03-26 15:00:24 +03:00
{
return get_format_by_name(cmd, av->value) ? 1 : 0;
2004-03-26 15:00:24 +03:00
}
static int _get_int_arg(struct arg_values *av, char **ptr)
2004-03-26 15:00:24 +03:00
{
char *val;
unsigned long long v;
2004-03-26 15:00:24 +03:00
av->percent = PERCENT_NONE;
val = av->value;
2004-03-26 15:00:24 +03:00
switch (*val) {
case '+':
av->sign = SIGN_PLUS;
2004-03-26 15:00:24 +03:00
val++;
break;
case '-':
av->sign = SIGN_MINUS;
2004-03-26 15:00:24 +03:00
val++;
break;
default:
av->sign = SIGN_NONE;
2004-03-26 15:00:24 +03:00
}
if (!isdigit(*val))
return 0;
errno = 0;
v = strtoull(val, ptr, 10);
2004-03-26 15:00:24 +03:00
if (*ptr == val || errno)
2004-03-26 15:00:24 +03:00
return 0;
av->i_value = (v < INT32_MAX) ? (int32_t) v : INT32_MAX;
av->ui_value = (v < UINT32_MAX) ? (uint32_t) v : UINT32_MAX;
av->i64_value = (v < INT64_MAX) ? (int64_t) v : INT64_MAX;
av->ui64_value = (v < UINT64_MAX) ? (uint64_t) v : UINT64_MAX;
2004-03-26 15:00:24 +03:00
return 1;
}
static int _get_percent_arg(struct arg_values *av, const char *ptr)
{
if (!strcasecmp(ptr, "V") || !strcasecmp(ptr, "VG"))
av->percent = PERCENT_VG;
else if (!strcasecmp(ptr, "L") || !strcasecmp(ptr, "LV"))
av->percent = PERCENT_LV;
else if (!strcasecmp(ptr, "P") || !strcasecmp(ptr, "PV") ||
!strcasecmp(ptr, "PVS"))
av->percent = PERCENT_PVS;
else if (!strcasecmp(ptr, "F") || !strcasecmp(ptr, "FR") ||
!strcasecmp(ptr, "FREE"))
av->percent = PERCENT_FREE;
else if (!strcasecmp(ptr, "O") || !strcasecmp(ptr, "OR") ||
!strcasecmp(ptr, "ORIGIN"))
av->percent = PERCENT_ORIGIN;
else {
log_error("Specified %%%s is unknown.", ptr);
return 0;
}
return 1;
}
/* Size stored in sectors */
static int _size_arg(struct cmd_context *cmd __attribute__((unused)),
struct arg_values *av, int factor, int percent)
2004-03-26 15:00:24 +03:00
{
char *ptr;
int i;
2024-05-03 13:38:39 +03:00
static const char _suffixes[] = "kmgtpebs";
2004-03-26 15:00:24 +03:00
char *val;
double v;
uint64_t v_tmp, adjustment;
const char *radixchar = nl_langinfo(RADIXCHAR) ? : ".";
2004-03-26 15:00:24 +03:00
av->percent = PERCENT_NONE;
val = av->value;
2004-03-26 15:00:24 +03:00
switch (*val) {
case '+':
av->sign = SIGN_PLUS;
2004-03-26 15:00:24 +03:00
val++;
break;
case '-':
av->sign = SIGN_MINUS;
2004-03-26 15:00:24 +03:00
val++;
break;
default:
av->sign = SIGN_NONE;
2004-03-26 15:00:24 +03:00
}
if (*val == '+' || *val == '-') {
log_error("Multiple sign symbols detected.");
2004-03-26 15:00:24 +03:00
return 0;
}
2004-03-26 15:00:24 +03:00
if (!isdigit(*val) && (*val != '.') && (*val != radixchar[0])) {
log_error("Size requires number argument.");
return 0;
}
errno = 0;
2004-03-26 15:00:24 +03:00
v = strtod(val, &ptr);
if (*ptr == '.' && radixchar[0] != '.') {
/*
* Maybe user has non-C locale with different decimal point ?
* Lets be tolerant and retry with standard C locales
*/
if (setlocale(LC_ALL, "C")) {
errno = 0;
v = strtod(val, &ptr);
setlocale(LC_ALL, "");
}
}
if (ptr == val || errno) {
log_error("Can't parse size argument at '%c'.%s%s", ptr[0], (errno) ? " " :"", (errno) ? strerror(errno) : "");
2004-03-26 15:00:24 +03:00
return 0;
}
2004-03-26 15:00:24 +03:00
if (percent && *ptr == '%') {
if (!_get_percent_arg(av, ++ptr))
return_0;
if ((uint64_t) v >= UINT32_MAX) {
log_error("Percentage is too big (>=%d%%).", UINT32_MAX);
return 0;
}
} else if (*ptr) {
2024-05-03 13:38:39 +03:00
for (i = sizeof(_suffixes) - 1; i >= 0; --i)
if (_suffixes[i] == tolower((int) *ptr))
2004-03-26 15:00:24 +03:00
break;
if (i < 0) {
log_error("Can't parse size argument.");
2004-03-26 15:00:24 +03:00
return 0;
} else if (i == 7) {
/* v is already in sectors */
;
} else if (i == 6) {
/* bytes */
v_tmp = (uint64_t) v;
adjustment = v_tmp % 512;
if (adjustment) {
v_tmp += (512 - adjustment);
log_error("Size is not a multiple of 512. "
"Try using %"PRIu64" or %"PRIu64".",
v_tmp - 512, v_tmp);
return 0;
}
v /= 512;
} else {
/* all other units: kmgtpe */
while (i-- > 0)
v *= 1024;
v *= 2;
}
2004-03-26 15:00:24 +03:00
} else
v *= factor;
/* Compare (double) */
if (v >= (double) (UINT64_MAX >> SECTOR_SHIFT)) {
log_error("Size is too big (>=16EiB).");
return 0;
}
av->i_value = ((int32_t) v < INT32_MAX) ? (int32_t) v : INT32_MAX;
av->ui_value = ((uint32_t) v < UINT32_MAX) ? (uint32_t) v : UINT32_MAX;
av->i64_value = ((int64_t) v < INT64_MAX) ? (int64_t) v : INT64_MAX;
av->ui64_value = ((uint64_t) v < UINT64_MAX) ? (uint64_t) v : UINT64_MAX;
2004-03-26 15:00:24 +03:00
return 1;
}
/* negative not accepted */
int size_kb_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!_size_arg(cmd, av, 2, 0))
return 0;
if (av->sign == SIGN_MINUS) {
log_error("Size may not be negative.");
return 0;
}
return 1;
}
int ssize_kb_arg(struct cmd_context *cmd, struct arg_values *av)
2004-03-26 15:00:24 +03:00
{
return _size_arg(cmd, av, 2, 0);
2004-03-26 15:00:24 +03:00
}
int size_mb_arg(struct cmd_context *cmd, struct arg_values *av)
2004-03-26 15:00:24 +03:00
{
if (!_size_arg(cmd, av, 2048, 0))
return 0;
if ((av->sign == SIGN_MINUS) || (av->sign == SIGN_PLUS)) {
log_error("Size may not be relative/signed.");
return 0;
}
return 1;
}
int ssize_mb_arg(struct cmd_context *cmd, struct arg_values *av)
{
return _size_arg(cmd, av, 2048, 0);
2004-03-26 15:00:24 +03:00
}
int psize_mb_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!_size_arg(cmd, av, 2048, 0))
return 0;
if (av->sign == SIGN_MINUS) {
log_error("Size may not be negative.");
return 0;
}
return 1;
}
int nsize_mb_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!_size_arg(cmd, av, 2048, 0))
return 0;
if (av->sign == SIGN_PLUS) {
log_error("Size may not be positive.");
return 0;
}
return 1;
}
int int_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
2004-03-26 15:00:24 +03:00
{
char *ptr;
if (!_get_int_arg(av, &ptr) || (*ptr) || (av->sign == SIGN_MINUS))
2004-03-26 15:00:24 +03:00
return 0;
return 1;
}
int uint32_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!int_arg(cmd, av) || (av->ui64_value > UINT32_MAX))
return 0;
return 1;
}
int int_arg_with_sign(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
2004-03-26 15:00:24 +03:00
{
char *ptr;
if (!_get_int_arg(av, &ptr) || (*ptr))
2004-03-26 15:00:24 +03:00
return 0;
return 1;
}
int int_arg_with_plus(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
{
char *ptr;
if (!_get_int_arg(av, &ptr) || (*ptr))
return 0;
if (av->sign == SIGN_MINUS) {
log_error("Number may not be negative.");
return 0;
}
return 1;
}
static int _extents_arg(struct cmd_context *cmd __attribute__((unused)),
struct arg_values *av)
{
char *ptr;
if (!_get_int_arg(av, &ptr))
return 0;
if (!*ptr)
return 1;
if (*ptr++ != '%')
return 0;
if (!_get_percent_arg(av, ptr))
return_0;
if (av->ui64_value >= UINT32_MAX) {
log_error("Percentage is too big (>=%d%%).", UINT32_MAX);
return 0;
}
return 1;
}
int extents_arg(struct cmd_context *cmd __attribute__((unused)),
struct arg_values *av)
{
if (!_extents_arg(cmd, av))
return 0;
if ((av->sign == SIGN_MINUS) || (av->sign == SIGN_PLUS)) {
log_error("Extents may not be relative/signed.");
return 0;
}
return 1;
}
int sextents_arg(struct cmd_context *cmd __attribute__((unused)),
struct arg_values *av)
{
return _extents_arg(cmd, av);
}
int pextents_arg(struct cmd_context *cmd __attribute__((unused)),
struct arg_values *av)
{
if (!_extents_arg(cmd, av))
return 0;
if (av->sign == SIGN_MINUS) {
log_error("Extents may not be negative.");
return 0;
}
return 1;
}
int nextents_arg(struct cmd_context *cmd __attribute__((unused)),
struct arg_values *av)
{
if (!_extents_arg(cmd, av))
return 0;
if (av->sign == SIGN_PLUS) {
log_error("Extents may not be positive.");
return 0;
}
return 1;
}
int string_arg(struct cmd_context *cmd __attribute__((unused)),
struct arg_values *av __attribute__((unused)))
2004-03-26 15:00:24 +03:00
{
return 1;
}
int tag_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
2004-03-26 15:00:24 +03:00
{
char *pos = av->value;
2004-03-26 15:00:24 +03:00
if (*pos == '@')
pos++;
if (!validate_tag(pos))
2004-03-26 15:00:24 +03:00
return 0;
av->value = pos;
2004-03-26 15:00:24 +03:00
return 1;
}
int permission_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
2004-03-26 15:00:24 +03:00
{
av->sign = SIGN_NONE;
2004-03-26 15:00:24 +03:00
if ((!strcmp(av->value, "rw")) || (!strcmp(av->value, "wr")))
av->ui_value = LVM_READ | LVM_WRITE;
2004-03-26 15:00:24 +03:00
else if (!strcmp(av->value, "r"))
av->ui_value = LVM_READ;
2004-03-26 15:00:24 +03:00
else
return 0;
return 1;
}
int alloc_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
{
alloc_policy_t alloc;
av->sign = SIGN_NONE;
alloc = get_alloc_from_string(av->value);
if (alloc == ALLOC_INVALID)
return 0;
av->ui_value = (uint32_t) alloc;
return 1;
}
2015-03-05 23:00:44 +03:00
int locktype_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
{
lock_type_t lock_type;
av->sign = SIGN_NONE;
lock_type = get_lock_type_from_string(av->value);
if (lock_type == LOCK_TYPE_INVALID)
return 0;
return 1;
}
int segtype_arg(struct cmd_context *cmd, struct arg_values *av)
{
struct segment_type *segtype;
const char *str = (!strcmp(av->value, SEG_TYPE_NAME_LINEAR)) ? SEG_TYPE_NAME_STRIPED : av->value;
if (!(segtype = get_segtype_from_string(cmd, str)))
return_0;
return (!segtype_is_unknown(segtype)) ? 1 : 0;
}
/*
* Positive integer, zero or "auto".
*/
int readahead_arg(struct cmd_context *cmd __attribute__((unused)), struct arg_values *av)
{
if (!strcasecmp(av->value, "auto")) {
av->ui_value = DM_READ_AHEAD_AUTO;
return 1;
}
if (!strcasecmp(av->value, "none")) {
av->ui_value = DM_READ_AHEAD_NONE;
return 1;
}
if (!_size_arg(cmd, av, 1, 0))
return 0;
if (av->sign == SIGN_MINUS)
return 0;
return 1;
}
int regionsize_mb_arg(struct cmd_context *cmd, struct arg_values *av)
{
int pagesize = lvm_getpagesize();
uint32_t num;
if (!_size_arg(cmd, av, 2048, 0))
return 0;
if (av->sign == SIGN_MINUS) {
log_error("Region size may not be negative.");
return 0;
}
if (av->ui64_value > UINT32_MAX) {
log_error("Region size is too big (max %u).", UINT32_MAX);
return 0;
}
num = av->ui_value;
if (!num) {
log_error("Region size may not be zero.");
return 0;
}
if (num % (pagesize >> SECTOR_SHIFT)) {
log_error("Region size must be a multiple of machine memory page size (%d bytes).",
pagesize);
return 0;
}
if (!is_power_of_2(num)) {
log_error("Region size must be a power of 2.");
return 0;
}
return 1;
}
/*
* Non-zero, positive integer, "all", or "unmanaged"
*/
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int vgmetadatacopies_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcasecmp(av->value, "all")) {
av->ui_value = VGMETADATACOPIES_ALL;
return 1;
}
if (!strcasecmp(av->value, "unmanaged")) {
av->ui_value = VGMETADATACOPIES_UNMANAGED;
return 1;
}
return int_arg(cmd, av);
}
int pvmetadatacopies_arg(struct cmd_context *cmd, struct arg_values *av)
{
int num;
if (!int_arg(cmd, av))
return 0;
num = av->i_value;
if ((num != 0) && (num != 1) && (num != 2))
return 0;
return 1;
}
int metadatacopies_arg(struct cmd_context *cmd, struct arg_values *av)
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (!strncmp(cmd->name, "pv", 2))
return pvmetadatacopies_arg(cmd, av);
if (!strncmp(cmd->name, "vg", 2))
return vgmetadatacopies_arg(cmd, av);
return 0;
}
int polloperation_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcmp(av->value, "pvmove") ||
!strcmp(av->value, "convert") ||
!strcmp(av->value, "merge") ||
!strcmp(av->value, "merge_thin"))
return 1;
return 0;
}
int writemostly_arg(struct cmd_context *cmd, struct arg_values *av)
{
/* Could we verify that a PV arg looks like /dev/foo ? */
return 1;
}
int syncaction_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcmp(av->value, "check") ||
!strcmp(av->value, "repair"))
return 1;
return 0;
}
int reportformat_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcmp(av->value, "basic") ||
!strcmp(av->value, "json") ||
!strcmp(av->value, "json_std"))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return 1;
return 0;
}
int configreport_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcmp(av->value, "log") ||
!strcmp(av->value, "vg") ||
!strcmp(av->value, "lv") ||
!strcmp(av->value, "pv") ||
!strcmp(av->value, "pvseg") ||
!strcmp(av->value, "seg"))
return 1;
return 0;
}
int configtype_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcmp(av->value, "current") ||
!strcmp(av->value, "default") ||
!strcmp(av->value, "diff") ||
!strcmp(av->value, "full") ||
!strcmp(av->value, "list") ||
!strcmp(av->value, "missing") ||
!strcmp(av->value, "new") ||
!strcmp(av->value, "profilable") ||
!strcmp(av->value, "profilable-command") ||
!strcmp(av->value, "profilable-metadata"))
return 1;
return 0;
}
int repairtype_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcmp(av->value, "pv_header") ||
!strcmp(av->value, "metadata") ||
!strcmp(av->value, "label_header"))
return 1;
return 0;
}
2019-12-10 20:06:45 +03:00
int dumptype_arg(struct cmd_context *cmd, struct arg_values *av)
{
if (!strcmp(av->value, "headers") ||
!strcmp(av->value, "metadata") ||
!strcmp(av->value, "metadata_all") ||
!strcmp(av->value, "metadata_search") ||
!strcmp(av->value, "metadata_area") ||
!strcmp(av->value, "backup_to_raw"))
return 1;
return 0;
}
int headings_arg(struct cmd_context *cmd, struct arg_values *av)
{
return report_headings_str_to_type(av->value) != REPORT_HEADINGS_UNKNOWN;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* FIXME: there's been a confusing mixup among:
* resizeable, resizable, allocatable, allocation.
*
* resizeable and allocatable are the preferred,
* standard option names.
*
* The dispreferred "resizable" is always translated
* to the preferred resizeable.
*
* But, the dispreferred "allocation" name seems
* to translate to either or both resizeable
* and allocatable, it's not clear which.
*/
static int _opt_standard_to_synonym(const char *cmd_name, int opt)
{
switch (opt) {
case mirrorlog_ARG:
return corelog_ARG;
case resizeable_ARG:
return resizable_ARG;
case allocatable_ARG:
return allocation_ARG;
case activate_ARG:
return available_ARG;
case rebuild_ARG:
return raidrebuild_ARG;
case syncaction_ARG:
return raidsyncaction_ARG;
case writemostly_ARG:
return raidwritemostly_ARG;
case minrecoveryrate_ARG:
return raidminrecoveryrate_ARG;
case maxrecoveryrate_ARG:
return raidmaxrecoveryrate_ARG;
case writebehind_ARG:
return raidwritebehind_ARG;
case virtualsize_ARG:
return virtualoriginsize_ARG;
case splitcache_ARG:
return split_ARG;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
case pvmetadatacopies_ARG:
if (!strncmp(cmd_name, "pv", 2))
return metadatacopies_ARG;
return 0;
case vgmetadatacopies_ARG:
if (!strncmp(cmd_name, "vg", 2))
return metadatacopies_ARG;
return 0;
}
return 0;
}
static int _opt_synonym_to_standard(const char *cmd_name, int opt)
{
switch (opt) {
case corelog_ARG:
return mirrorlog_ARG;
case resizable_ARG:
return resizeable_ARG;
case allocation_ARG:
return allocatable_ARG;
case available_ARG:
return activate_ARG;
case raidrebuild_ARG:
return rebuild_ARG;
case raidsyncaction_ARG:
return syncaction_ARG;
case raidwritemostly_ARG:
return writemostly_ARG;
case raidminrecoveryrate_ARG:
return minrecoveryrate_ARG;
case raidmaxrecoveryrate_ARG:
return maxrecoveryrate_ARG;
case raidwritebehind_ARG:
return writebehind_ARG;
case virtualoriginsize_ARG:
return virtualsize_ARG;
case split_ARG:
return splitcache_ARG;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
case metadatacopies_ARG:
if (!strncmp(cmd_name, "pv", 2))
return pvmetadatacopies_ARG;
if (!strncmp(cmd_name, "vg", 2))
return vgmetadatacopies_ARG;
return 0;
}
return 0;
}
static void _add_getopt_arg(int arg_enum, char **optstrp, struct option **longoptsp);
/*
* The valid args for a command name in general is a union of
* required_opt_args and optional_opt_args for all commands[]
* with the given name.
*/
static void _set_valid_args_for_command_name(int ci)
{
int all_args[ARG_COUNT] = { 0 };
int num_args = 0;
int opt_enum; /* foo_ARG from args.h */
int opt_syn;
2017-04-03 23:24:46 +03:00
int i, ro, oo, io;
int first = 0, last = COMMAND_COUNT - 1, middle;
const char *name = command_names[ci].name;
/* all_args is indexed by the foo_ARG enum vals */
/* Binary search in sorted array of long options (with duplicates) */
while (first <= last) {
middle = first + (last - first) / 2;
if ((i = strcmp(commands_idx[middle]->name, name)) < 0)
first = middle + 1;
else if (i > 0)
last = middle - 1;
else {
/* Matching command found.
* As sorted array contains duplicates, found 1st. and last such cmd. */
i = middle;
while (middle > first && !strcmp(commands_idx[middle - 1]->name, name))
middle--;
while (i < last && !strcmp(commands_idx[i + 1]->name, name))
i++;
last = i;
break;
}
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
while (middle <= last) {
i = commands_idx[middle++]->command_index;
for (ro = 0; ro < (commands[i].ro_count + commands[i].any_ro_count); ro++) {
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
opt_enum = commands[i].required_opt_args[ro].opt;
all_args[opt_enum] = 1;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
for (oo = 0; oo < commands[i].oo_count; oo++) {
opt_enum = commands[i].optional_opt_args[oo].opt;
all_args[opt_enum] = 1;
}
2017-04-03 23:24:46 +03:00
for (io = 0; io < commands[i].io_count; io++) {
opt_enum = commands[i].ignore_opt_args[io].opt;
all_args[opt_enum] = 1;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
for (i = 0; i < ARG_COUNT; i++) {
if (all_args[i]) {
opt_enum = _cmdline.opt_names[i].opt_enum;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
command_names[ci].valid_args[num_args] = opt_enum;
num_args++;
/* Automatically recognize --extents in addition to --size. */
if (opt_enum == size_ARG) {
command_names[ci].valid_args[num_args] = extents_ARG;
num_args++;
}
/* Recognize synonyms */
if ((opt_syn = _opt_standard_to_synonym(command_names[ci].name, opt_enum))) {
command_names[ci].valid_args[num_args] = opt_syn;
num_args++;
}
/*
* "--allocation" is a weird option that seems to be
* a synonym for either allocatable or resizeable,
* each which already have their own other synonyms,
* so just add allocation whenever either is seen.
*/
if ((opt_enum == allocatable_ARG) || (opt_enum == resizeable_ARG)) {
command_names[ci].valid_args[num_args] = allocation_ARG;
num_args++;
}
}
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
command_names[ci].num_args = num_args;
}
2017-02-18 20:50:22 +03:00
static const struct command_function *_find_command_id_function(int command_enum)
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
{
int i;
if (!command_enum)
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return NULL;
for (i = 0; i < CMD_COUNT; i++) {
if (_command_functions[i].command_enum == command_enum)
return &_command_functions[i];
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
return NULL;
}
partial revert "command: Skip some memory zeroing." This partially reverts commit da37cbd24fc0073f3f00a3b7aac7807d2185b829. As the _cmdline structure use mempool for allocated ellement that is being release on cmd_context close. Before the better fix is made - restore previous logic and reinitialize cmd structures again for new cmd_context. Problem can be hit with e.g. this test run: make check_local T=foreign LVM_VALGRIND_DMEVENTD=1 Invalid read of size 1 at 0x4C31C83: strcmp (vg_replace_strmem.c:846) by 0x6BA0939: _find_command (lvmcmdline.c:1555) by 0x6BA4304: lvm_run_command (lvmcmdline.c:2810) by 0x6BD5E02: lvm2_run (lvmcmdlib.c:91) by 0x685607E: dmeventd_lvm2_run (dmeventd_lvm.c:118) by 0x6652684: _use_policy (dmeventd_thin.c:117) by 0x6652E56: process_event (dmeventd_thin.c:298) by 0x10CC5A: _do_process_event (dmeventd.c:945) by 0x10CF83: _monitor_thread (dmeventd.c:1033) by 0x54B35E0: start_thread (in /usr/lib64/libpthread-2.26.9000.so) by 0x57C30EE: clone (in /usr/lib64/libc-2.26.9000.so) Address 0x6266270 is 4,352 bytes inside a block of size 8,192 free'd at 0x4C2ED68: free (vg_replace_malloc.c:530) by 0x5289142: dm_free_wrapper (dbg_malloc.c:393) by 0x528998A: _free_chunk (pool-fast.c:318) by 0x52892A6: dm_pool_destroy (pool-fast.c:78) by 0x6A8E52C: destroy_toolcontext (toolcontext.c:2254) by 0x6BA5BD6: lvm_fin (lvmcmdline.c:3327) by 0x6BD5EA7: lvm2_exit (lvmcmdlib.c:123) by 0x6856013: dmeventd_lvm2_exit (dmeventd_lvm.c:103) by 0x66535B8: unregister_device (dmeventd_thin.c:432) by 0x10CBBC: _do_unregister_device (dmeventd.c:926) by 0x10CD74: _monitor_unregister (dmeventd.c:979) by 0x10D094: _monitor_thread (dmeventd.c:1066) by 0x54B35E0: start_thread (in /usr/lib64/libpthread-2.26.9000.so) by 0x57C30EE: clone (in /usr/lib64/libc-2.26.9000.so) Block was alloc'd at at 0x4C2DBBB: malloc (vg_replace_malloc.c:299) by 0x5288F46: dm_malloc_aux (dbg_malloc.c:287) by 0x52890AC: dm_malloc_wrapper (dbg_malloc.c:371) by 0x52898E6: _new_chunk (pool-fast.c:286) by 0x52893BA: dm_pool_alloc_aligned (pool-fast.c:106) by 0x5289310: dm_pool_alloc (pool-fast.c:90) by 0x6A8A21A: _load_config_file (toolcontext.c:808) by 0x6A8A3D9: _init_lvm_conf (toolcontext.c:842) by 0x6A8D3BD: create_toolcontext (toolcontext.c:1941) by 0x6BA5B24: init_lvm (lvmcmdline.c:3308) by 0x6BD5B7C: cmdlib_lvm2_init (lvmcmdlib.c:34) by 0x6BD5EB8: lvm2_init (lvm2cmd.c:20) by 0x6855EA7: dmeventd_lvm2_init (dmeventd_lvm.c:67) by 0x665305F: register_device (dmeventd_thin.c:352) by 0x10CB7A: _do_register_device (dmeventd.c:916) by 0x10CEE4: _monitor_thread (dmeventd.c:1006) by 0x54B35E0: start_thread (in /usr/lib64/libpthread-2.26.9000.so) by 0x57C30EE: clone (in /usr/lib64/libc-2.26.9000.so)
2018-02-09 12:51:02 +03:00
static void _unregister_commands(void)
{
_cmdline.commands = NULL;
_cmdline.num_commands = 0;
_cmdline.command_names = NULL;
_cmdline.num_command_names = 0;
}
static int _command_name_compare(const void *on1, const void *on2)
{
const struct command * const *optname1 = on1;
const struct command * const *optname2 = on2;
return strcmp((*optname1)->name, (*optname2)->name);
}
int lvm_register_commands(struct cmd_context *cmd, const char *run_name)
2004-03-26 15:00:24 +03:00
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int i;
const char *last_name = NULL;
const struct command_name *cname = NULL;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* already initialized */
if (_cmdline.commands)
return 1;
/*
* populate commands[] array with command definitions
* by parsing command-lines.in/command-lines-input.h
*/
if (!define_commands(cmd, run_name)) {
log_error(INTERNAL_ERROR "Failed to parse command definitions.");
return 0;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
_cmdline.commands = commands;
_cmdline.num_commands = COMMAND_COUNT;
for (i = 0; i < COMMAND_COUNT; i++) {
commands_idx[i] = &commands[i];
commands[i].command_index = i;
commands[i].command_enum = command_id_to_enum(commands[i].command_id);
if (!commands[i].command_enum) {
log_error(INTERNAL_ERROR "Failed to find command id %s.", commands[i].command_id);
_cmdline.commands = NULL;
_cmdline.num_commands = 0;
return 0;
}
/* new style */
commands[i].functions = _find_command_id_function(commands[i].command_enum);
/* old style */
if (!commands[i].functions) {
if (!last_name || strcmp(last_name, commands[i].name)) {
last_name = commands[i].name;
cname = find_command_name(last_name);
}
if (cname)
commands[i].fn = cname->fn;
}
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* Sort all commands by its name for quick binary search */
qsort(commands_idx, COMMAND_COUNT, sizeof(long), _command_name_compare);
for (i = 0; command_names[i].name; i++)
_set_valid_args_for_command_name(i);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
_cmdline.num_command_names = i; /* Also counted how many command entries we have */
_cmdline.command_names = command_names;
2004-03-26 15:00:24 +03:00
return 1;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
struct command *get_command(int cmd_enum)
{
int i;
for (i = 0; i < COMMAND_COUNT; i++) {
if (commands[i].command_enum == cmd_enum)
return &commands[i];
}
return NULL;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* Also see merge_synonym(). The command definitions
* are written using just one variation of the option
* name (opt below). This function checks if the user
* entered a synonym (arg_is_set).
*/
static int _opt_synonym_is_set(struct cmd_context *cmd, int opt_std)
2004-03-26 15:00:24 +03:00
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int opt_syn = _opt_standard_to_synonym(cmd->name, opt_std);
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return opt_syn && arg_is_set(cmd, opt_syn);
2004-03-26 15:00:24 +03:00
}
static int _command_optional_opt_matches(struct cmd_context *cmd, int ci, int oo)
{
int opt_enum = commands[ci].optional_opt_args[oo].opt;
if (val_bit_is_set(commands[ci].optional_opt_args[oo].def.val_bits, conststr_VAL)) {
if (!strcmp(commands[ci].optional_opt_args[oo].def.str, arg_str_value(cmd, opt_enum, "")))
return 1;
return 0;
}
if (val_bit_is_set(commands[ci].optional_opt_args[oo].def.val_bits, constnum_VAL)) {
if (commands[ci].optional_opt_args[oo].def.num == arg_uint64_value(cmd, opt_enum, 0))
return 1;
return 0;
}
return 1;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
static int _command_ignore_opt_matches(struct cmd_context *cmd, int ci, int io)
2004-03-26 15:00:24 +03:00
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int opt_enum = commands[ci].ignore_opt_args[io].opt;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (val_bit_is_set(commands[ci].ignore_opt_args[io].def.val_bits, conststr_VAL)) {
if (!strcmp(commands[ci].ignore_opt_args[io].def.str, arg_str_value(cmd, opt_enum, "")))
return 1;
return 0;
}
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (val_bit_is_set(commands[ci].ignore_opt_args[io].def.val_bits, constnum_VAL)) {
if (commands[ci].ignore_opt_args[io].def.num == arg_uint64_value(cmd, opt_enum, 0))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return 1;
return 0;
}
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return 1;
2004-03-26 15:00:24 +03:00
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
static int _command_required_opt_matches(struct cmd_context *cmd, int ci, int ro)
2004-03-26 15:00:24 +03:00
{
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int opt_enum = commands[ci].required_opt_args[ro].opt;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (arg_is_set(cmd, opt_enum) || _opt_synonym_is_set(cmd, opt_enum))
goto check_val;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* For some commands, --size and --extents are interchangable,
* but command[] definitions use only --size.
*/
if ((opt_enum == size_ARG) && arg_is_set(cmd, extents_ARG) &&
command_has_alternate_extents(commands[ci].name))
goto check_val;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return 0;
/*
* If the definition requires a literal string or number, check
* that the arg value matches.
*/
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
check_val:
if (val_bit_is_set(commands[ci].required_opt_args[ro].def.val_bits, conststr_VAL)) {
if (!strcmp(commands[ci].required_opt_args[ro].def.str, arg_str_value(cmd, opt_enum, "")))
return 1;
/* Special case: "raid0" (any raid<N>), matches command def "raid" */
if (!strcmp(commands[ci].required_opt_args[ro].def.str, "raid") &&
!strncmp(arg_str_value(cmd, opt_enum, ""), "raid", 4))
return 1;
return 0;
}
if (val_bit_is_set(commands[ci].required_opt_args[ro].def.val_bits, constnum_VAL)) {
if (commands[ci].required_opt_args[ro].def.num == arg_uint64_value(cmd, opt_enum, 0))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return 1;
return 0;
}
return 1;
2004-03-26 15:00:24 +03:00
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
static int _command_required_pos_matches(struct cmd_context *cmd, int ci, int rp, char **argv)
2004-03-26 15:00:24 +03:00
{
2024-04-28 23:09:05 +03:00
unsigned i;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* rp is the index in required_pos_args[] of the required positional arg.
* The pos values begin with 1, so the first positional arg has
* pos 1, rp 0.
*/
if (argv[rp]) {
/* FIXME: can we match object type better than just checking something exists? */
/* Some cases could be validated by looking at defs.types and at the value. */
return 1;
}
/*
* If Select is specified as a pos arg, then that pos arg can be
* empty if --select is used.
*/
if ((val_bit_is_set(commands[ci].required_pos_args[rp].def.val_bits, select_VAL)) &&
arg_is_set(cmd, select_ARG))
return 1;
/*
* For an lvcreate command with VG as the first required positional arg,
* the VG position is allowed to be empty if --name VG/LV is used, or if the
* LVM_VG_NAME env var is set.
*
* --thinpool|--cachepool|--vdopool VG/LV can also function like --name
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
* to provide the VG name in place of the positional arg.
*/
if (!strcmp(cmd->name, "lvcreate") &&
(rp == 0) &&
2024-04-28 23:09:05 +03:00
val_bit_is_set(commands[ci].required_pos_args[rp].def.val_bits, vg_VAL)) {
const char *names[] = {
arg_str_value(cmd, name_ARG, NULL),
arg_str_value(cmd, thinpool_ARG, NULL),
arg_str_value(cmd, cachepool_ARG, NULL),
arg_str_value(cmd, vdopool_ARG, NULL),
};
if (getenv("LVM_VG_NAME"))
return 1;
2024-04-28 23:09:05 +03:00
for (i = 0; i < DM_ARRAY_SIZE(names); ++i)
/* Check whether LV name has VG name separated by '/' */
if (names[i] && (strstr(names[i], "/")))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return 1;
}
return 0;
2004-03-26 15:00:24 +03:00
}
/*
* Return 1 if we should skip this command from consideration.
* This would happen if the command does not include a --type
* option that does not match type_arg.
*/
static int _command_skip_for_type_arg(struct cmd_context *cmd, int ci, const char *type_arg)
{
int ro, oo, opt_enum;
for (ro = 0; ro < (commands[ci].ro_count + commands[ci].any_ro_count); ro++) {
opt_enum = commands[ci].required_opt_args[ro].opt;
if (opt_enum != type_ARG)
continue;
/* SegType keyword in command def matches any type_arg */
if (val_bit_is_set(commands[ci].required_opt_args[ro].def.val_bits, segtype_VAL))
return 0;
if (!commands[ci].required_opt_args[ro].def.str)
return 0;
if (!strcmp(commands[ci].required_opt_args[ro].def.str, type_arg))
return 0;
if (!strncmp(commands[ci].required_opt_args[ro].def.str, "raid", 4) &&
!strncmp(type_arg, "raid", 4))
return 0;
return 1;
}
for (oo = 0; oo < commands[ci].oo_count; oo++) {
opt_enum = commands[ci].optional_opt_args[oo].opt;
if (opt_enum != type_ARG)
continue;
/* SegType keyword in command def matches any type_arg */
if (val_bit_is_set(commands[ci].optional_opt_args[oo].def.val_bits, segtype_VAL))
return 0;
if (!commands[ci].optional_opt_args[oo].def.str)
return 0;
if (!strcmp(commands[ci].optional_opt_args[oo].def.str, type_arg))
return 0;
if (!strncmp(commands[ci].optional_opt_args[oo].def.str, "raid", 4) &&
!strncmp(type_arg, "raid", 4))
return 0;
return 1;
}
return 1;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* Match what the user typed with a one specific command definition/prototype
* from commands[]. If nothing matches, it's not a valid command. The match
* is based on command name, required opt args and required pos args.
*
* Find an entry in the commands array that matches based the arg values.
*
* If the cmd has opt or pos args set that are not accepted by command,
* we can: silently ignore them, warn they are not being used, or fail.
* Default should probably be to warn and continue.
*
* For each command[i], check how many required opt/pos args cmd matches.
* Save the command[i] that matches the most.
*
* commands[i].cmd_flags & CMD_FLAG_ANY_REQUIRED_OPT means
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
* any one item from commands[i].required_opt_args needs to be
* set to match.
*
* required_pos_args[0].types & select_VAL means
* argv[] in that pos can be NULL if arg_is_set(select_ARG)
*/
/* The max number of unused options we keep track of to warn about */
#define MAX_UNUSED_COUNT 8
#define MAX_OPTS_MSG 64
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
static struct command *_find_command(struct cmd_context *cmd, const char *path, int *argc, char **argv)
{
const char *name;
const char *type_arg = NULL;
char opts_msg[MAX_OPTS_MSG];
char check_opts_msg[MAX_OPTS_MSG];
int match_required, match_ro, match_rp, match_any_ro, match_type, match_unused, mismatch_required;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int best_i = 0, best_required = 0, best_type = 0, best_unused = 0;
int close_i = 0, close_ro = 0, close_type = 0;
int only_i = 0;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int temp_unused_options[MAX_UNUSED_COUNT];
int temp_unused_count;
int best_unused_options[MAX_UNUSED_COUNT] = { 0 };
int best_unused_count = 0;
int opts_match_count, opts_unmatch_count;
int ro, rp;
int i, j;
int opt_enum, opt_i;
int accepted, count;
int variants = 0;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
name = last_path_component(path);
/* factor_common_options() is only for usage, so cname->variants is not set. */
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
for (i = 0; i < COMMAND_COUNT; i++) {
if (strcmp(name, commands[i].name))
continue;
variants++;
}
if (arg_is_set(cmd, type_ARG))
type_arg = arg_str_value(cmd, type_ARG, "");
for (i = 0; i < COMMAND_COUNT; i++) {
if (strcmp(name, commands[i].name))
continue;
if (variants == 1)
only_i = i;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* For help and version just return the first entry with matching name. */
if (arg_is_set(cmd, help_ARG) || arg_is_set(cmd, help2_ARG) || arg_is_set(cmd, longhelp_ARG) || arg_is_set(cmd, version_ARG))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return &commands[i];
/*
* The 'lvconvert LV' cmd def matches any lvconvert cmd which throws off
* nearest-command partial-match suggestions. Make it a special case so
* that it won't be used as a close match. If the command has any option
* set (other than -v), don't attempt to match it to 'lvconvert LV'.
*/
if (commands[i].command_enum == lvconvert_plain_CMD) {
if (cmd->opt_count - cmd->opt_arg_values[verbose_ARG].count)
continue;
}
/*
* If the cmd def has an implied type, specified in AUTOTYPE,
* then if the user command has --type, it must match.
*/
if (type_arg && commands[i].autotype && strcmp(type_arg, commands[i].autotype))
continue;
if (type_arg && commands[i].autotype2 && strcmp(type_arg, commands[i].autotype2))
continue;
/*
* '--type foo' is special. If the user has set --type foo, then
* we will only look at command defs that include the same --type foo
* (as required or optional). We'll never match some command based
* on *other* (non-type) options, and then at the end complain that
* the user's --type is not accepted.
*/
if (type_arg && _command_skip_for_type_arg(cmd, i, type_arg))
continue;
match_required = 0; /* required parameters that match */
match_ro = 0; /* required opt_args that match */
match_rp = 0; /* required pos_args that match */
match_any_ro = 0;
match_type = 0; /* type arg matches */
match_unused = 0; /* options set that are not accepted by command */
mismatch_required = 0; /* required parameters that do not match */
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
temp_unused_count = 0;
memset(&temp_unused_options, 0, sizeof(temp_unused_options));
/* if the command name alone is enough, then that's a match */
if (!commands[i].ro_count && !commands[i].rp_count)
match_required = 1;
/* match required_opt_args */
for (ro = 0; ro < commands[i].ro_count; ro++) {
if (_command_required_opt_matches(cmd, i, ro)) {
/* log_warn("match %d ro opt %d", i, commands[i].required_opt_args[ro].opt); */
match_required++;
match_ro++;
if (commands[i].required_opt_args[ro].opt == type_ARG)
match_type = 1;
} else {
/* cmd is missing a required opt arg */
/* log_warn("mismatch %d ro opt %d", i, commands[i].required_opt_args[ro].opt); */
mismatch_required++;
}
}
for (ro = commands[i].ro_count; ro < commands[i].ro_count + commands[i].any_ro_count; ro++) {
if (_command_required_opt_matches(cmd, i, ro)) {
/* log_warn("match %d any ro opt %d", i, commands[i].required_opt_args[ro].opt); */
match_any_ro++;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
}
if ((commands[i].cmd_flags & CMD_FLAG_ANY_REQUIRED_OPT) && !match_any_ro) {
/* not even one of the any ro is used */
/* log_warn("match %d not one from any", i); */
mismatch_required = 1;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* match required_pos_args */
for (rp = 0; rp < commands[i].rp_count; rp++) {
if (_command_required_pos_matches(cmd, i, rp, argv)) {
/* log_warn("match %d rp %d", i, commands[i].required_pos_args[rp].pos); */
match_required++;
match_rp++;
} else {
/* cmd is missing a required pos arg */
/* log_warn("mismatch %d rp %d", i, commands[i].required_pos_args[rp].pos); */
mismatch_required++;
}
}
/* if cmd is missing any required opt/pos args, it can't be this command. */
if (mismatch_required) {
/* save "closest" command that doesn't match */
if ((match_type && !close_type) ||
((match_type == close_type) && (match_ro > close_ro))) {
close_i = i;
close_ro = match_ro;
close_type = match_type;
}
continue;
}
if (!match_required)
continue;
/* Count the command name as a match if all the required opt/pos args match. */
if ((commands[i].ro_count || commands[i].rp_count) && (match_ro || match_rp))
match_required++;
/* log_warn("command %d has match_required %d match_ro %d match_rp %d",
i, match_required, match_ro, match_rp); */
/* Count how many options cmd has set that are not accepted by commands[i]. */
/* FIXME: also count unused positional args? */
for (opt_i = 0; opt_i < ARG_COUNT; opt_i++) {
if (!arg_is_set(cmd, opt_i))
continue;
if (!(opt_enum = _opt_synonym_to_standard(cmd->name, opt_i)))
opt_enum = opt_i;
/* extents are not used in command definitions */
if (opt_enum == extents_ARG)
continue;
accepted = 0;
/* NB in some cases required_opt_args are optional */
for (j = 0; j < commands[i].ro_count + commands[i].any_ro_count; j++) {
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (commands[i].required_opt_args[j].opt == opt_enum) {
accepted = 1;
break;
}
}
if (accepted)
continue;
for (j = 0; j < commands[i].oo_count; j++) {
if ((commands[i].optional_opt_args[j].opt == opt_enum) &&
_command_optional_opt_matches(cmd, i, j)) {
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
accepted = 1;
break;
}
}
for (j = 0; j < commands[i].io_count; j++) {
if ((commands[i].ignore_opt_args[j].opt == opt_enum) &&
_command_ignore_opt_matches(cmd, i, j)) {
accepted = 1;
break;
}
}
if (!accepted) {
match_unused++;
if (temp_unused_count < MAX_UNUSED_COUNT)
temp_unused_options[temp_unused_count++] = opt_enum;
}
}
/*
* Choose the best match, which in general is the command with
* the most matching required_{opt,pos}, but it could be a
* command with fewer required_{opt,pos} matches in the case
* where cmddef1 has more required matches, but a match_unused
* and cmddef2 has fewer required matches, but zero match_unused.
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
*
* A match is better if:
* . more required opt/pos args match
* . type arg matches when other doesn't
* . less unused options
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
*/
if (!best_required ||
((match_required > best_required) && !match_unused) ||
(match_unused < best_unused) ||
(match_type > best_type) ||
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
((match_required == best_required) && (match_type == best_type) && (match_unused < best_unused))) {
/* log_warn("best %d has match_required %d match_ro %d match_rp %d",
i, match_required, match_ro, match_rp); */
best_i = i;
best_required = match_required;
best_type = match_type;
best_unused = match_unused;
best_unused_count = temp_unused_count;
memcpy(&best_unused_options, &temp_unused_options, sizeof(best_unused_options));
}
}
if (!best_required) {
/* cmd did not have all the required opt/pos args of any command */
log_error("No command with matching syntax recognised. Run '%s --help' for more information.", name);
if (only_i) {
log_warn("Correct command syntax is:");
print_usage(&_cmdline.commands[only_i], 0, 0);
} else if (close_ro) {
2017-03-02 18:37:54 +03:00
log_warn("Nearest similar command has syntax:");
print_usage(&_cmdline.commands[close_i], 0, 0);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
return NULL;
}
/*
* If the user passed an option that is not accepted by the matched
* command, then fail.
*
* FIXME: it might be nice to have a config setting that would turn
* these into warnings, and just ignore the unused options.
*/
if (best_unused_count) {
for (i = 0; i < best_unused_count; i++) {
const char *opt_val = NULL;
opt_enum = best_unused_options[i];
opt_val = arg_value(cmd, opt_enum);
log_error("Command does not accept option: %s%s%s.",
arg_long_option_name(opt_enum),
opt_val ? " " : "", opt_val ?: "");
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
return NULL;
}
/*
* If the user provided a positional arg that is not accepted by
* the mached command, then fail.
*
* If the last required_pos_arg or the last optional_pos_arg may repeat,
* then there won't be unused positional args.
*
* FIXME: same question as above, should there be a config setting
* to just warn/ignore about unused positional args?
*/
count = commands[best_i].rp_count;
if (count && (commands[best_i].required_pos_args[count - 1].def.flags & ARG_DEF_FLAG_MAY_REPEAT))
goto out;
count = commands[best_i].op_count;
if (count && (commands[best_i].optional_pos_args[count - 1].def.flags & ARG_DEF_FLAG_MAY_REPEAT))
goto out;
for (count = 0; ; count++) {
if (!argv[count])
break;
if (count >= (commands[best_i].rp_count + commands[best_i].op_count)) {
log_error("Command does not accept argument: %s.", argv[count]);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* FIXME: to warn/ignore, clear so it can't be used when processing. */
/*
argv[count] = NULL;
(*argc)--;
*/
return NULL;
}
}
out:
/*
* Check any rules related to option combinations.
* Other rules are checked after VG is read.
*/
for (i = 0; i < commands[best_i].rule_count; i++) {
struct cmd_rule *rule;
rule = &commands[best_i].rules[i];
/*
* The rule wants to validate options (check_opts). That can be
* done here if the only qualification for the validation is
* other options (and not specific LV type or LV property which
* are not known here.)
*/
if (rule->check_opts_count && !rule->lvt_bits && !rule->lvp_bits) {
/*
* When no opt is specified for applying the rule, then
* the rule is always applied, otherwise the rule is
* applied when the specific option is set.
*/
if (rule->opts_count &&
!opt_in_list_is_set(cmd, rule->opts, rule->opts_count, NULL, NULL))
continue;
opt_in_list_is_set(cmd, rule->check_opts, rule->check_opts_count,
&opts_match_count, &opts_unmatch_count);
if (opts_match_count && (rule->rule == RULE_INVALID)) {
memset(opts_msg, 0, sizeof(opts_msg));
memset(check_opts_msg, 0, sizeof(check_opts_msg));
if (rule->opts_count)
opt_array_to_str(cmd, rule->opts, rule->opts_count, opts_msg, sizeof(opts_msg));
opt_array_to_str(cmd, rule->check_opts, rule->check_opts_count, check_opts_msg, sizeof(check_opts_msg));
if (rule->opts_count)
log_error("Command does not accept option combination: %s with %s", opts_msg, check_opts_msg);
else
log_error("Command does not accept options: %s", check_opts_msg);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return NULL;
}
if (opts_unmatch_count && (rule->rule == RULE_REQUIRE)) {
memset(check_opts_msg, 0, sizeof(check_opts_msg));
opt_array_to_str(cmd, rule->check_opts, rule->check_opts_count, check_opts_msg, sizeof(check_opts_msg));
log_error("Command requires options: %s", check_opts_msg);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return NULL;
}
}
}
log_debug("Recognised command %s (id %d / enum %d).",
commands[best_i].command_id, best_i, commands[best_i].command_enum);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
log_command(cmd->cmd_line, commands[best_i].name, commands[best_i].command_id);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return &commands[best_i];
2004-03-26 15:00:24 +03:00
}
static void _short_usage(const char *name)
{
log_error("Run `%s --help' for more information.", name);
}
static int _usage(const char *name, int longhelp, int skip_notes)
2004-03-26 15:00:24 +03:00
{
const struct command_name *cname = find_command_name(name);
struct command *cmd = NULL;
int show_full = longhelp;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int i;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (!cname) {
log_print("%s: no such command.", name);
return 0;
}
2004-03-26 15:00:24 +03:00
/*
* Looks at all variants of each command name and figures out
* which options are common to all variants (for compact output)
*/
factor_common_options();
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
log_print("%s - %s\n", name, cname->desc);
/* Reduce the default output when there are several variants. */
if (cname->variants < 3)
show_full = 1;
for (i = 0; i < COMMAND_COUNT; i++) {
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (strcmp(_cmdline.commands[i].name, name))
continue;
if (_cmdline.commands[i].cmd_flags & CMD_FLAG_PREVIOUS_SYNTAX)
continue;
if ((_cmdline.commands[i].cmd_flags & CMD_FLAG_SECONDARY_SYNTAX) && !show_full)
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
continue;
log_very_verbose("Command definition index %d enum %d id %s",
_cmdline.commands[i].command_index,
_cmdline.commands[i].command_enum,
_cmdline.commands[i].command_id);
print_usage(&_cmdline.commands[i], 1, 1);
cmd = &_cmdline.commands[i];
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
/* Common options are printed once for all variants of a command name. */
if (!cmd) {
log_error(INTERNAL_ERROR "Command %s not found.", name);
return 0;
}
print_usage_common_cmd(cname, cmd);
print_usage_common_lvm(cname, cmd);
if (skip_notes)
return 1;
if (longhelp)
print_usage_notes(cname);
else
log_print("Use --longhelp to show all options and advanced commands.");
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return 1;
2004-03-26 15:00:24 +03:00
}
static void _usage_all(void)
{
int i;
for (i = 0; command_names[i].name; i++)
_usage(command_names[i].name, 1, 1);
print_usage_notes(NULL);
}
2004-03-26 15:00:24 +03:00
/*
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
* Sets up the arguments to pass to getopt_long().
*
* getopt_long() takes a string of short option characters
* where the char is followed by ":" if the option takes an arg,
* e.g. "abc:d:" This string is created in optstrp.
*
* getopt_long() also takes an array of struct option which
* has the name of the long option, if it takes an arg, etc,
* e.g.
*
* option long_options[] = {
* { "foo", required_argument, 0, 0 },
* { "bar", no_argument, 0, 'b' }
* };
*
* this array is created in longoptsp.
*
* Original comment:
2004-03-26 15:00:24 +03:00
* Sets up the short and long argument. If there
* is no short argument then the index of the
* argument in the the_args array is set as the
* long opt value. Yuck. Of course this means we
* can't have more than 'a' long arguments.
*/
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
static void _add_getopt_arg(int opt_enum, char **optstrp, struct option **longoptsp)
2004-03-26 15:00:24 +03:00
{
const struct opt_name *a = _cmdline.opt_names + opt_enum;
2004-03-26 15:00:24 +03:00
if (a->short_opt) {
*(*optstrp)++ = a->short_opt;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (a->val_enum)
*(*optstrp)++ = ':';
2004-03-26 15:00:24 +03:00
}
#ifdef HAVE_GETOPTLONG
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* long_arg is "--foo", so +2 is the offset of the name after "--" */
if (*(a->long_opt + 2)) {
(*longoptsp)->name = a->long_opt + 2;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
(*longoptsp)->has_arg = a->val_enum ? 1 : 0;
(*longoptsp)->flag = NULL;
/*
* When getopt_long() sees an option that has an associated
* single letter, it returns the ascii value of that letter.
* e.g. getopt_long() returns 100 for '-d' or '--debug'
* (100 is the ascii value of 'd').
*
* When getopt_long() sees an option that does not have an
* associated single letter, it returns the value of the
* the enum for that long option name plus 128.
* e.g. getopt_long() returns 139 for --cachepool
* (11 is the enum value for --cachepool, so 11+128)
*/
if (a->short_opt)
(*longoptsp)->val = a->short_opt;
2004-03-26 15:00:24 +03:00
else
(*longoptsp)->val = opt_enum + 128;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
(*longoptsp)++;
2004-03-26 15:00:24 +03:00
}
#endif
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* getopt_long() has returned goval which indicates which option it's found.
* We need to translate that goval to an enum value from the args array.
*
* For options with both long and short forms, goval is the character value
* of the short option. For options with only a long form, goval is the
* corresponding enum value plus 128.
*
* The trick with character values is that different long options share the
* same single-letter short form. So, we have to translate goval to an
* enum using only the set of valid options for the given command. And,
* a command name is not allowed to use two different long options that
* have the same single-letter short form.
*/
static int _find_arg(const char *cmd_name, int goval)
2004-03-26 15:00:24 +03:00
{
const struct command_name *cname;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int arg_enum;
int i;
2004-03-26 15:00:24 +03:00
if (!(cname = find_command_name(cmd_name)))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return -1;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
for (i = 0; i < cname->num_args; i++) {
arg_enum = cname->valid_args[i];
/* assert arg_enum == _cmdline.opt_names[arg_enum].arg_enum */
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* the value returned by getopt matches the ascii value of single letter option */
if (_cmdline.opt_names[arg_enum].short_opt && (goval == _cmdline.opt_names[arg_enum].short_opt))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_enum;
/* the value returned by getopt matches the enum value plus 128 */
if (!_cmdline.opt_names[arg_enum].short_opt && (goval == (arg_enum + 128)))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
return arg_enum;
2004-03-26 15:00:24 +03:00
}
return -1;
2004-03-26 15:00:24 +03:00
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
static int _process_command_line(struct cmd_context *cmd, int *argc, char ***argv)
2004-03-26 15:00:24 +03:00
{
char str[((ARG_COUNT + 1) * 2) + 1], *ptr = str;
struct option opts[ARG_COUNT + 1], *o = opts;
const struct opt_name *a;
struct arg_values *av;
struct arg_value_group_list *current_group = NULL;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int arg_enum; /* e.g. foo_ARG */
int val_enum;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
int goval; /* the number returned from getopt_long identifying what it found */
int i;
if (!(cmd->opt_arg_values = dm_pool_zalloc(cmd->mem, sizeof(*cmd->opt_arg_values) * ARG_COUNT))) {
log_fatal("Unable to allocate memory for command line arguments.");
return 0;
2004-03-26 15:00:24 +03:00
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* create the short-form character array (str) and the long-form option
* array (opts) to pass to the getopt_long() function. IOW we generate
* the arguments to pass to getopt_long() from the opt_names data.
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
*/
if (cmd->cname)
for (i = 0; i < cmd->cname->num_args; i++)
_add_getopt_arg(cmd->cname->valid_args[i], &ptr, &o);
2004-03-26 15:00:24 +03:00
*ptr = '\0';
memset(o, 0, sizeof(*o));
optarg = (char*) "";
2004-03-26 15:00:24 +03:00
optind = OPTIND_INIT;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
while ((goval = GETOPTLONG_FN(*argc, *argv, str, opts, NULL)) >= 0) {
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (goval == '?')
2004-03-26 15:00:24 +03:00
return 0;
cmd->opt_count++;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* translate the option value used by getopt into the enum
* value (e.g. foo_ARG) from the args array.
*/
if ((arg_enum = _find_arg(cmd->name, goval)) < 0) {
log_fatal("Unrecognised option %d (%c).", goval, goval);
2004-03-26 15:00:24 +03:00
return 0;
}
a = _cmdline.opt_names + arg_enum;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
av = &cmd->opt_arg_values[arg_enum];
if (a->flags & ARG_NONINTERACTIVE && cmd->is_interactive) {
log_error("Argument%s%c%s%s cannot be used in interactive mode.",
a->short_opt ? " -" : "",
a->short_opt ? : ' ',
(a->short_opt && a->long_opt) ?
"/" : "", a->long_opt ? : "");
return 0;
}
if (a->flags & ARG_GROUPABLE) {
/*
* Start a new group of arguments:
* - the first time,
* - or if a non-countable argument is repeated,
* - or if argument has higher priority than current group.
*/
if (!current_group ||
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
(current_group->arg_values[arg_enum].count && !(a->flags & ARG_COUNTABLE)) ||
(current_group->prio < a->prio)) {
/* FIXME Reduce size including only groupable args */
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (!(current_group = dm_pool_zalloc(cmd->mem, sizeof(struct arg_value_group_list) + sizeof(*cmd->opt_arg_values) * ARG_COUNT))) {
log_fatal("Unable to allocate memory for command line arguments.");
return 0;
}
current_group->prio = a->prio;
dm_list_add(&cmd->arg_value_groups, &current_group->list);
}
/* Maintain total argument count as well as count within each group */
av->count++;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
av = &current_group->arg_values[arg_enum];
}
if (av->count && !(a->flags & ARG_COUNTABLE)) {
log_error("Option%s%c%s%s may not be repeated.",
a->short_opt ? " -" : "",
a->short_opt ? : ' ',
(a->short_opt && a->long_opt) ?
"/" : "", a->long_opt ? : "");
return 0;
}
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (a->val_enum) {
2004-03-26 15:00:24 +03:00
if (!optarg) {
log_error("Option requires argument.");
return 0;
}
av->value = optarg;
val_enum = configure_command_option_values(cmd->cname, arg_enum, a->val_enum);
if (!get_val_name(val_enum)->fn(cmd, av)) {
log_error("Invalid argument for %s: %s", a->long_opt, optarg);
2004-03-26 15:00:24 +03:00
return 0;
}
}
av->count++;
2004-03-26 15:00:24 +03:00
}
*argc -= optind;
*argv += optind;
return 1;
}
static void _copy_arg_values(struct arg_values *av, int oldarg, int newarg)
{
const struct arg_values *old = av + oldarg;
struct arg_values *new = av + newarg;
new->count = old->count;
new->value = old->value;
new->i_value = old->i_value;
new->ui_value = old->ui_value;
new->i64_value = old->i64_value;
new->ui64_value = old->ui64_value;
new->sign = old->sign;
}
2004-03-26 15:00:24 +03:00
static int _merge_synonym(struct cmd_context *cmd, int oldarg, int newarg)
{
struct arg_values *av;
struct arg_value_group_list *current_group;
2004-03-26 15:00:24 +03:00
if (arg_is_set(cmd, oldarg) && arg_is_set(cmd, newarg)) {
2004-03-26 15:00:24 +03:00
log_error("%s and %s are synonyms. Please only supply one.",
_cmdline.opt_names[oldarg].long_opt, _cmdline.opt_names[newarg].long_opt);
2004-03-26 15:00:24 +03:00
return 0;
}
/* Not groupable? */
if (!(_cmdline.opt_names[oldarg].flags & ARG_GROUPABLE)) {
if (arg_is_set(cmd, oldarg))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
_copy_arg_values(cmd->opt_arg_values, oldarg, newarg);
2004-03-26 15:00:24 +03:00
return 1;
}
2004-03-26 15:00:24 +03:00
if (arg_is_set(cmd, oldarg))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
cmd->opt_arg_values[newarg].count = cmd->opt_arg_values[oldarg].count;
2004-03-26 15:00:24 +03:00
/* Groupable */
dm_list_iterate_items(current_group, &cmd->arg_value_groups) {
av = current_group->arg_values;
if (!grouped_arg_count(av, oldarg))
continue;
_copy_arg_values(av, oldarg, newarg);
}
2004-03-26 15:00:24 +03:00
return 1;
}
int systemid(struct cmd_context *cmd __attribute__((unused)),
int argc __attribute__((unused)),
char **argv __attribute__((unused)))
{
log_print("system ID: %s", cmd->system_id ? : "");
return ECMD_PROCESSED;
}
int version(struct cmd_context *cmd __attribute__((unused)),
int argc __attribute__((unused)),
char **argv __attribute__((unused)))
2004-03-26 15:00:24 +03:00
{
char vsn[80];
log_print("LVM version: %s", LVM_VERSION);
if (library_version(vsn, sizeof(vsn)))
log_print("Library version: %s", vsn);
if (driver_version(vsn, sizeof(vsn)))
log_print("Driver version: %s", vsn);
log_print("Configuration: %s", LVM_CONFIGURE_LINE);
2004-03-26 15:00:24 +03:00
return ECMD_PROCESSED;
}
static void _reset_current_settings_to_default(struct cmd_context *cmd)
{
cmd->current_settings = cmd->default_settings;
}
static void _get_current_output_settings_from_args(struct cmd_context *cmd)
2004-03-26 15:00:24 +03:00
{
if (arg_is_set(cmd, udevoutput_ARG)) {
pvscan: add options listlvs listvg checkcomplete pvscan --cache <dev> . read only dev . create online file for dev pvscan --listvg <dev> . read only dev . list VG using dev pvscan --listlvs <dev> . read only dev . list VG using dev . list LVs using dev pvscan --cache --listvg [--checkcomplete] <dev> . read only dev . create online file for dev . list VG using dev . [check online files and report if VG is complete] pvscan --cache --listlvs [--checkcomplete] <dev> . read only dev . create online file for dev . list VG using dev . list LVs using dev . [check online files and report if VG is complete] . [check online files and report if LVs are complete] [--vgonline] can be used with --checkcomplete, to enable use of a vg online file. This results in only the first pvscan command to see the complete VG to report 'VG complete', and others will report 'VG finished'. This allows the caller to easily run a single activation of the VG. [--udevoutput] can be used with --cache --listvg --checkcomplete, to enable an output mode that prints LVM_VG_NAME_COMPLETE='vgname' that a udev rule can import, and prevents other output from the command (other output causes udev to ignore the command.) The list of complete LVs is meant to be passed to lvchange -aay, or the complete VG used with vgchange -aay. When --checkcomplete is used, lvm assumes that that the output will be used to trigger event-based autoactivation, so the pvscan does nothing if event_activation=0 and --checkcomplete is used. Example of listlvs ------------------ $ lvs -a vg -olvname,devices LV Devices lv_a /dev/loop0(0) lv_ab /dev/loop0(1),/dev/loop1(1) lv_abc /dev/loop0(3),/dev/loop1(3),/dev/loop2(1) lv_b /dev/loop1(0) lv_c /dev/loop2(0) $ pvscan --cache --listlvs --checkcomplete /dev/loop0 pvscan[35680] PV /dev/loop0 online, VG vg incomplete (need 2). VG vg incomplete LV vg/lv_a complete LV vg/lv_ab incomplete LV vg/lv_abc incomplete $ pvscan --cache --listlvs --checkcomplete /dev/loop1 pvscan[35681] PV /dev/loop1 online, VG vg incomplete (need 1). VG vg incomplete LV vg/lv_b complete LV vg/lv_ab complete LV vg/lv_abc incomplete $ pvscan --cache --listlvs --checkcomplete /dev/loop2 pvscan[35682] PV /dev/loop2 online, VG vg is complete. VG vg complete LV vg/lv_c complete LV vg/lv_abc complete Example of listvg ----------------- $ pvscan --cache --listvg --checkcomplete /dev/loop0 pvscan[35684] PV /dev/loop0 online, VG vg incomplete (need 2). VG vg incomplete $ pvscan --cache --listvg --checkcomplete /dev/loop1 pvscan[35685] PV /dev/loop1 online, VG vg incomplete (need 1). VG vg incomplete $ pvscan --cache --listvg --checkcomplete /dev/loop2 pvscan[35686] PV /dev/loop2 online, VG vg is complete. VG vg complete
2020-12-09 19:59:40 +03:00
cmd->current_settings.suppress = 1;
cmd->udevoutput = 1;
}
pvscan: add options listlvs listvg checkcomplete pvscan --cache <dev> . read only dev . create online file for dev pvscan --listvg <dev> . read only dev . list VG using dev pvscan --listlvs <dev> . read only dev . list VG using dev . list LVs using dev pvscan --cache --listvg [--checkcomplete] <dev> . read only dev . create online file for dev . list VG using dev . [check online files and report if VG is complete] pvscan --cache --listlvs [--checkcomplete] <dev> . read only dev . create online file for dev . list VG using dev . list LVs using dev . [check online files and report if VG is complete] . [check online files and report if LVs are complete] [--vgonline] can be used with --checkcomplete, to enable use of a vg online file. This results in only the first pvscan command to see the complete VG to report 'VG complete', and others will report 'VG finished'. This allows the caller to easily run a single activation of the VG. [--udevoutput] can be used with --cache --listvg --checkcomplete, to enable an output mode that prints LVM_VG_NAME_COMPLETE='vgname' that a udev rule can import, and prevents other output from the command (other output causes udev to ignore the command.) The list of complete LVs is meant to be passed to lvchange -aay, or the complete VG used with vgchange -aay. When --checkcomplete is used, lvm assumes that that the output will be used to trigger event-based autoactivation, so the pvscan does nothing if event_activation=0 and --checkcomplete is used. Example of listlvs ------------------ $ lvs -a vg -olvname,devices LV Devices lv_a /dev/loop0(0) lv_ab /dev/loop0(1),/dev/loop1(1) lv_abc /dev/loop0(3),/dev/loop1(3),/dev/loop2(1) lv_b /dev/loop1(0) lv_c /dev/loop2(0) $ pvscan --cache --listlvs --checkcomplete /dev/loop0 pvscan[35680] PV /dev/loop0 online, VG vg incomplete (need 2). VG vg incomplete LV vg/lv_a complete LV vg/lv_ab incomplete LV vg/lv_abc incomplete $ pvscan --cache --listlvs --checkcomplete /dev/loop1 pvscan[35681] PV /dev/loop1 online, VG vg incomplete (need 1). VG vg incomplete LV vg/lv_b complete LV vg/lv_ab complete LV vg/lv_abc incomplete $ pvscan --cache --listlvs --checkcomplete /dev/loop2 pvscan[35682] PV /dev/loop2 online, VG vg is complete. VG vg complete LV vg/lv_c complete LV vg/lv_abc complete Example of listvg ----------------- $ pvscan --cache --listvg --checkcomplete /dev/loop0 pvscan[35684] PV /dev/loop0 online, VG vg incomplete (need 2). VG vg incomplete $ pvscan --cache --listvg --checkcomplete /dev/loop1 pvscan[35685] PV /dev/loop1 online, VG vg incomplete (need 1). VG vg incomplete $ pvscan --cache --listvg --checkcomplete /dev/loop2 pvscan[35686] PV /dev/loop2 online, VG vg is complete. VG vg complete
2020-12-09 19:59:40 +03:00
if (arg_is_set(cmd, debug_ARG))
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
cmd->current_settings.debug = _LOG_FATAL + (arg_count(cmd, debug_ARG) - 1);
2004-03-26 15:00:24 +03:00
if (arg_is_set(cmd, verbose_ARG))
cmd->current_settings.verbose = arg_count(cmd, verbose_ARG);
if (arg_is_set(cmd, quiet_ARG)) {
2004-03-26 15:00:24 +03:00
cmd->current_settings.debug = 0;
cmd->current_settings.verbose = 0;
cmd->current_settings.silent = (arg_count(cmd, quiet_ARG) > 1) ? 1 : 0;
2004-03-26 15:00:24 +03:00
}
/*
* default_settings.journal is already set from config and has already been
* applied using init_log_journal().
* current_settings have been set to default_settings.
* now --journal value adds to current_settings.
*/
if (arg_is_set(cmd, journal_ARG))
cmd->current_settings.journal |= log_journal_str_to_val(arg_str_value(cmd, journal_ARG, ""));
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
static void _apply_current_output_settings(struct cmd_context *cmd)
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
{
pvscan: add options listlvs listvg checkcomplete pvscan --cache <dev> . read only dev . create online file for dev pvscan --listvg <dev> . read only dev . list VG using dev pvscan --listlvs <dev> . read only dev . list VG using dev . list LVs using dev pvscan --cache --listvg [--checkcomplete] <dev> . read only dev . create online file for dev . list VG using dev . [check online files and report if VG is complete] pvscan --cache --listlvs [--checkcomplete] <dev> . read only dev . create online file for dev . list VG using dev . list LVs using dev . [check online files and report if VG is complete] . [check online files and report if LVs are complete] [--vgonline] can be used with --checkcomplete, to enable use of a vg online file. This results in only the first pvscan command to see the complete VG to report 'VG complete', and others will report 'VG finished'. This allows the caller to easily run a single activation of the VG. [--udevoutput] can be used with --cache --listvg --checkcomplete, to enable an output mode that prints LVM_VG_NAME_COMPLETE='vgname' that a udev rule can import, and prevents other output from the command (other output causes udev to ignore the command.) The list of complete LVs is meant to be passed to lvchange -aay, or the complete VG used with vgchange -aay. When --checkcomplete is used, lvm assumes that that the output will be used to trigger event-based autoactivation, so the pvscan does nothing if event_activation=0 and --checkcomplete is used. Example of listlvs ------------------ $ lvs -a vg -olvname,devices LV Devices lv_a /dev/loop0(0) lv_ab /dev/loop0(1),/dev/loop1(1) lv_abc /dev/loop0(3),/dev/loop1(3),/dev/loop2(1) lv_b /dev/loop1(0) lv_c /dev/loop2(0) $ pvscan --cache --listlvs --checkcomplete /dev/loop0 pvscan[35680] PV /dev/loop0 online, VG vg incomplete (need 2). VG vg incomplete LV vg/lv_a complete LV vg/lv_ab incomplete LV vg/lv_abc incomplete $ pvscan --cache --listlvs --checkcomplete /dev/loop1 pvscan[35681] PV /dev/loop1 online, VG vg incomplete (need 1). VG vg incomplete LV vg/lv_b complete LV vg/lv_ab complete LV vg/lv_abc incomplete $ pvscan --cache --listlvs --checkcomplete /dev/loop2 pvscan[35682] PV /dev/loop2 online, VG vg is complete. VG vg complete LV vg/lv_c complete LV vg/lv_abc complete Example of listvg ----------------- $ pvscan --cache --listvg --checkcomplete /dev/loop0 pvscan[35684] PV /dev/loop0 online, VG vg incomplete (need 2). VG vg incomplete $ pvscan --cache --listvg --checkcomplete /dev/loop1 pvscan[35685] PV /dev/loop1 online, VG vg incomplete (need 1). VG vg incomplete $ pvscan --cache --listvg --checkcomplete /dev/loop2 pvscan[35686] PV /dev/loop2 online, VG vg is complete. VG vg complete
2020-12-09 19:59:40 +03:00
log_suppress(cmd->current_settings.suppress);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
init_debug(cmd->current_settings.debug);
init_debug_classes_logged(cmd->default_settings.debug_classes);
init_verbose(cmd->current_settings.verbose + VERBOSE_BASE_LEVEL);
init_silent(cmd->current_settings.silent);
init_log_journal(cmd->current_settings.journal);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
}
device usage based on devices file The LVM devices file lists devices that lvm can use. The default file is /etc/lvm/devices/system.devices, and the lvmdevices(8) command is used to add or remove device entries. If the file does not exist, or if lvm.conf includes use_devicesfile=0, then lvm will not use a devices file. When the devices file is in use, the regex filter is not used, and the filter settings in lvm.conf or on the command line are ignored. LVM records devices in the devices file using hardware-specific IDs, such as the WWID, and attempts to use subsystem-specific IDs for virtual device types. These device IDs are also written in the VG metadata. When no hardware or virtual ID is available, lvm falls back using the unstable device name as the device ID. When devnames are used, lvm performs extra scanning to find devices if their devname changes, e.g. after reboot. When proper device IDs are used, an lvm command will not look at devices outside the devices file, but when devnames are used as a fallback, lvm will scan devices outside the devices file to locate PVs on renamed devices. A config setting search_for_devnames can be used to control the scanning for renamed devname entries. Related to the devices file, the new command option --devices <devnames> allows a list of devices to be specified for the command to use, overriding the devices file. The listed devices act as a sort of devices file in terms of limiting which devices lvm will see and use. Devices that are not listed will appear to be missing to the lvm command. Multiple devices files can be kept in /etc/lvm/devices, which allows lvm to be used with different sets of devices, e.g. system devices do not need to be exposed to a specific application, and the application can use lvm on its own set of devices that are not exposed to the system. The option --devicesfile <filename> is used to select the devices file to use with the command. Without the option set, the default system devices file is used. Setting --devicesfile "" causes lvm to not use a devices file. An existing, empty devices file means lvm will see no devices. The new command vgimportdevices adds PVs from a VG to the devices file and updates the VG metadata to include the device IDs. vgimportdevices -a will import all VGs into the system devices file. LVM commands run by dmeventd not use a devices file by default, and will look at all devices on the system. A devices file can be created for dmeventd (/etc/lvm/devices/dmeventd.devices) If this file exists, lvm commands run by dmeventd will use it. Internal implementaion: - device_ids_read - read the devices file . add struct dev_use (du) to cmd->use_devices for each devices file entry - dev_cache_scan - get /dev entries . add struct device (dev) to dev_cache for each device on the system - device_ids_match - match devices file entries to /dev entries . match each du on cmd->use_devices to a dev in dev_cache, using device ID . on match, set du->dev, dev->id, dev->flags MATCHED_USE_ID - label_scan - read lvm headers and metadata from devices . filters are applied, those that do not need data from the device . filter-deviceid skips devs without MATCHED_USE_ID, i.e. skips /dev entries that are not listed in the devices file . read lvm label from dev . filters are applied, those that use data from the device . read lvm metadata from dev . add info/vginfo structs for PVs/VGs (info is "lvmcache") - device_ids_find_renamed_devs - handle devices with unstable devname ID where devname changed . this step only needed when devs do not have proper device IDs, and their dev names change, e.g. after reboot sdb becomes sdc. . detect incorrect match because PVID in the devices file entry does not match the PVID found when the device was read above . undo incorrect match between du and dev above . search system devices for new location of PVID . update devices file with new devnames for PVIDs on renamed devices . label_scan the renamed devs - continue with command processing
2020-06-23 21:25:41 +03:00
static int _read_devices_list(struct cmd_context *cmd)
{
struct arg_value_group_list *group;
const char *names;
struct dm_list *names_list;
dm_list_iterate_items(group, &cmd->arg_value_groups) {
if (!grouped_arg_is_set(group->arg_values, devices_ARG))
continue;
if (!(names = (char *)grouped_arg_str_value(group->arg_values, devices_ARG, NULL)))
continue;
if (!strchr(names, ',')) {
if (!str_list_add(cmd->mem, &cmd->deviceslist, names))
return 0;
} else {
if ((names_list = str_to_str_list(cmd->mem, names, ",", 1)))
dm_list_splice(&cmd->deviceslist, names_list);
}
}
return 1;
}
static int _get_current_settings(struct cmd_context *cmd)
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
{
const char *activation_mode;
const char *hint_mode;
device usage based on devices file The LVM devices file lists devices that lvm can use. The default file is /etc/lvm/devices/system.devices, and the lvmdevices(8) command is used to add or remove device entries. If the file does not exist, or if lvm.conf includes use_devicesfile=0, then lvm will not use a devices file. When the devices file is in use, the regex filter is not used, and the filter settings in lvm.conf or on the command line are ignored. LVM records devices in the devices file using hardware-specific IDs, such as the WWID, and attempts to use subsystem-specific IDs for virtual device types. These device IDs are also written in the VG metadata. When no hardware or virtual ID is available, lvm falls back using the unstable device name as the device ID. When devnames are used, lvm performs extra scanning to find devices if their devname changes, e.g. after reboot. When proper device IDs are used, an lvm command will not look at devices outside the devices file, but when devnames are used as a fallback, lvm will scan devices outside the devices file to locate PVs on renamed devices. A config setting search_for_devnames can be used to control the scanning for renamed devname entries. Related to the devices file, the new command option --devices <devnames> allows a list of devices to be specified for the command to use, overriding the devices file. The listed devices act as a sort of devices file in terms of limiting which devices lvm will see and use. Devices that are not listed will appear to be missing to the lvm command. Multiple devices files can be kept in /etc/lvm/devices, which allows lvm to be used with different sets of devices, e.g. system devices do not need to be exposed to a specific application, and the application can use lvm on its own set of devices that are not exposed to the system. The option --devicesfile <filename> is used to select the devices file to use with the command. Without the option set, the default system devices file is used. Setting --devicesfile "" causes lvm to not use a devices file. An existing, empty devices file means lvm will see no devices. The new command vgimportdevices adds PVs from a VG to the devices file and updates the VG metadata to include the device IDs. vgimportdevices -a will import all VGs into the system devices file. LVM commands run by dmeventd not use a devices file by default, and will look at all devices on the system. A devices file can be created for dmeventd (/etc/lvm/devices/dmeventd.devices) If this file exists, lvm commands run by dmeventd will use it. Internal implementaion: - device_ids_read - read the devices file . add struct dev_use (du) to cmd->use_devices for each devices file entry - dev_cache_scan - get /dev entries . add struct device (dev) to dev_cache for each device on the system - device_ids_match - match devices file entries to /dev entries . match each du on cmd->use_devices to a dev in dev_cache, using device ID . on match, set du->dev, dev->id, dev->flags MATCHED_USE_ID - label_scan - read lvm headers and metadata from devices . filters are applied, those that do not need data from the device . filter-deviceid skips devs without MATCHED_USE_ID, i.e. skips /dev entries that are not listed in the devices file . read lvm label from dev . filters are applied, those that use data from the device . read lvm metadata from dev . add info/vginfo structs for PVs/VGs (info is "lvmcache") - device_ids_find_renamed_devs - handle devices with unstable devname ID where devname changed . this step only needed when devs do not have proper device IDs, and their dev names change, e.g. after reboot sdb becomes sdc. . detect incorrect match because PVID in the devices file entry does not match the PVID found when the device was read above . undo incorrect match between du and dev above . search system devices for new location of PVID . update devices file with new devnames for PVIDs on renamed devices . label_scan the renamed devs - continue with command processing
2020-06-23 21:25:41 +03:00
const char *search_mode;
2004-03-26 15:00:24 +03:00
_get_current_output_settings_from_args(cmd);
if (arg_is_set(cmd, test_ARG))
cmd->current_settings.test = arg_is_set(cmd, test_ARG);
cmd->current_settings.yes = arg_count(cmd, yes_ARG);
if (arg_is_set(cmd, driverloaded_ARG)) {
2004-03-26 15:00:24 +03:00
cmd->current_settings.activation =
arg_int_value(cmd, driverloaded_ARG,
cmd->default_settings.activation);
}
cmd->current_settings.archive = arg_int_value(cmd, autobackup_ARG, cmd->current_settings.archive);
cmd->current_settings.backup = arg_int_value(cmd, autobackup_ARG, cmd->current_settings.backup);
if (arg_is_set(cmd, readonly_ARG)) {
cmd->current_settings.activation = 0;
cmd->current_settings.archive = 0;
cmd->current_settings.backup = 0;
}
if (cmd->cname->flags & LOCKD_VG_SH)
2015-03-05 23:00:44 +03:00
cmd->lockd_vg_default_sh = 1;
if (cmd->cname->flags & CAN_USE_ONE_SCAN)
cmd->can_use_one_scan = 1;
exported vg handling The exported VG checking/enforcement was scattered and inconsistent. This centralizes it and makes it consistent, following the existing approach for foreign and shared VGs/PVs, which are very similar to exported VGs/PVs. The access policy that now applies to foreign/shared/exported VGs/PVs, is that if a foreign/shared/exported VG/PV is named on the command line (i.e. explicitly requested by the user), and the command is not permitted to operate on it because it is foreign/shared/exported, then an access error is reported and the command exits with an error. But, if the command is processing all VGs/PVs, and happens to come across a foreign/shared/exported VG/PV (that is not explicitly named on the command line), then the command silently skips it and does not produce an error. A command using tags or --select handles inaccessible VGs/PVs the same way as a command processing all VGs/PVs, and will not report/return errors if these inaccessible VGs/PVs exist. The new policy fixes the exit codes on a somewhat random set of commands that previously exited with an error if they were looking at all VGs/PVs and an exported VG existed on the system. There should be no change to which commands are allowed/disallowed on exported VGs/PVs. Certain LV commands (lvs/lvdisplay/lvscan) would previously not display LVs from an exported VG (for unknown reasons). This has not changed. The lvm fullreport command would previously report info about an exported VG but not about the LVs in it. This has changed to include all info from the exported VG.
2019-06-21 21:37:11 +03:00
cmd->include_exported_vgs = (cmd->cname->flags & ALLOW_EXPORTED) ? 1 : 0;
cmd->scan_lvs = find_config_tree_bool(cmd, devices_scan_lvs_CFG, NULL);
cmd->allow_mixed_block_sizes = find_config_tree_bool(cmd, devices_allow_mixed_block_sizes_CFG, NULL);
cmd->check_devs_used = (cmd->cname->flags & CHECK_DEVS_USED) ? 1 : 0;
cmd->print_device_id_not_found = (cmd->cname->flags & DEVICE_ID_NOT_FOUND) ? 1 : 0;
/*
* enable_hints is set to 1 if any commands are using hints.
* use_hints is set to 1 if this command should use the hints.
* enable_hints=1 and use_hints=0 means that this command won't
* use the hints, but it may invalidate the hints that are used
* by other commands.
*
* enable_hints=0 means no commands are using hints, so this
* command would not need to invalidate hints for other cmds.
*
* Code should check !enable_hints before checking use_hints.
*/
cmd->enable_hints = 1;
/* Only certain commands need to be optimized by using hints. */
if (cmd->cname->flags & ALLOW_HINTS)
cmd->use_hints = 1;
else
cmd->use_hints = 0;
device usage based on devices file The LVM devices file lists devices that lvm can use. The default file is /etc/lvm/devices/system.devices, and the lvmdevices(8) command is used to add or remove device entries. If the file does not exist, or if lvm.conf includes use_devicesfile=0, then lvm will not use a devices file. When the devices file is in use, the regex filter is not used, and the filter settings in lvm.conf or on the command line are ignored. LVM records devices in the devices file using hardware-specific IDs, such as the WWID, and attempts to use subsystem-specific IDs for virtual device types. These device IDs are also written in the VG metadata. When no hardware or virtual ID is available, lvm falls back using the unstable device name as the device ID. When devnames are used, lvm performs extra scanning to find devices if their devname changes, e.g. after reboot. When proper device IDs are used, an lvm command will not look at devices outside the devices file, but when devnames are used as a fallback, lvm will scan devices outside the devices file to locate PVs on renamed devices. A config setting search_for_devnames can be used to control the scanning for renamed devname entries. Related to the devices file, the new command option --devices <devnames> allows a list of devices to be specified for the command to use, overriding the devices file. The listed devices act as a sort of devices file in terms of limiting which devices lvm will see and use. Devices that are not listed will appear to be missing to the lvm command. Multiple devices files can be kept in /etc/lvm/devices, which allows lvm to be used with different sets of devices, e.g. system devices do not need to be exposed to a specific application, and the application can use lvm on its own set of devices that are not exposed to the system. The option --devicesfile <filename> is used to select the devices file to use with the command. Without the option set, the default system devices file is used. Setting --devicesfile "" causes lvm to not use a devices file. An existing, empty devices file means lvm will see no devices. The new command vgimportdevices adds PVs from a VG to the devices file and updates the VG metadata to include the device IDs. vgimportdevices -a will import all VGs into the system devices file. LVM commands run by dmeventd not use a devices file by default, and will look at all devices on the system. A devices file can be created for dmeventd (/etc/lvm/devices/dmeventd.devices) If this file exists, lvm commands run by dmeventd will use it. Internal implementaion: - device_ids_read - read the devices file . add struct dev_use (du) to cmd->use_devices for each devices file entry - dev_cache_scan - get /dev entries . add struct device (dev) to dev_cache for each device on the system - device_ids_match - match devices file entries to /dev entries . match each du on cmd->use_devices to a dev in dev_cache, using device ID . on match, set du->dev, dev->id, dev->flags MATCHED_USE_ID - label_scan - read lvm headers and metadata from devices . filters are applied, those that do not need data from the device . filter-deviceid skips devs without MATCHED_USE_ID, i.e. skips /dev entries that are not listed in the devices file . read lvm label from dev . filters are applied, those that use data from the device . read lvm metadata from dev . add info/vginfo structs for PVs/VGs (info is "lvmcache") - device_ids_find_renamed_devs - handle devices with unstable devname ID where devname changed . this step only needed when devs do not have proper device IDs, and their dev names change, e.g. after reboot sdb becomes sdc. . detect incorrect match because PVID in the devices file entry does not match the PVID found when the device was read above . undo incorrect match between du and dev above . search system devices for new location of PVID . update devices file with new devnames for PVIDs on renamed devices . label_scan the renamed devs - continue with command processing
2020-06-23 21:25:41 +03:00
/* The hints file is associated with the default/system devices file. */
if (arg_is_set(cmd, devicesfile_ARG) || arg_is_set(cmd, devices_ARG))
cmd->use_hints = 0;
/*
* During system init, hints are repeatedly invalidated due to PVs
* appearing, so it's wasted effort to try to maintain hints.
* Hints are only effective when devices are in a steady-state.
*/
if (arg_is_set(cmd, sysinit_ARG))
cmd->use_hints = 0;
/*
* Don't use hints from this command, but enable_hints will
* remain set unless hints=none in the config. See above re
* the meaning of use_hints=0 && enable_hints=1.
*/
if (arg_is_set(cmd, nohints_ARG))
cmd->use_hints = 0;
if ((hint_mode = find_config_tree_str(cmd, devices_hints_CFG, NULL))) {
if (!strcmp(hint_mode, "none")) {
cmd->enable_hints = 0;
cmd->use_hints = 0;
}
}
2008-09-19 11:12:45 +04:00
cmd->partial_activation = 0;
activation: Add "degraded" activation mode Currently, we have two modes of activation, an unnamed nominal mode (which I will refer to as "complete") and "partial" mode. The "complete" mode requires that a volume group be 'complete' - that is, no missing PVs. If there are any missing PVs, no affected LVs are allowed to activate - even RAID LVs which might be able to tolerate a failure. The "partial" mode allows anything to be activated (or at least attempted). If a non-redundant LV is missing a portion of its addressable space due to a device failure, it will be replaced with an error target. RAID LVs will either activate or fail to activate depending on how badly their redundancy is compromised. This patch adds a third option, "degraded" mode. This mode can be selected via the '--activationmode {complete|degraded|partial}' option to lvchange/vgchange. It can also be set in lvm.conf. The "degraded" activation mode allows RAID LVs with a sufficient level of redundancy to activate (e.g. a RAID5 LV with one device failure, a RAID6 with two device failures, or RAID1 with n-1 failures). RAID LVs with too many device failures are not allowed to activate - nor are any non-redundant LVs that may have been affected. This patch also makes the "degraded" mode the default activation mode. The degraded activation mode does not yet work in a cluster. A new cluster lock flag (LCK_DEGRADED_MODE) will need to be created to make that work. Currently, there is limited space for this extra flag and I am looking for possible solutions. One possible solution is to usurp LCK_CONVERT, as it is not used. When the locking_type is 3, the degraded mode flag simply gets dropped and the old ("complete") behavior is exhibited.
2014-07-10 07:56:11 +04:00
cmd->degraded_activation = 0;
activation_mode = find_config_tree_str(cmd, activation_mode_CFG, NULL);
if (!activation_mode)
activation_mode = DEFAULT_ACTIVATION_MODE;
if (arg_is_set(cmd, activationmode_ARG)) {
activation: Add "degraded" activation mode Currently, we have two modes of activation, an unnamed nominal mode (which I will refer to as "complete") and "partial" mode. The "complete" mode requires that a volume group be 'complete' - that is, no missing PVs. If there are any missing PVs, no affected LVs are allowed to activate - even RAID LVs which might be able to tolerate a failure. The "partial" mode allows anything to be activated (or at least attempted). If a non-redundant LV is missing a portion of its addressable space due to a device failure, it will be replaced with an error target. RAID LVs will either activate or fail to activate depending on how badly their redundancy is compromised. This patch adds a third option, "degraded" mode. This mode can be selected via the '--activationmode {complete|degraded|partial}' option to lvchange/vgchange. It can also be set in lvm.conf. The "degraded" activation mode allows RAID LVs with a sufficient level of redundancy to activate (e.g. a RAID5 LV with one device failure, a RAID6 with two device failures, or RAID1 with n-1 failures). RAID LVs with too many device failures are not allowed to activate - nor are any non-redundant LVs that may have been affected. This patch also makes the "degraded" mode the default activation mode. The degraded activation mode does not yet work in a cluster. A new cluster lock flag (LCK_DEGRADED_MODE) will need to be created to make that work. Currently, there is limited space for this extra flag and I am looking for possible solutions. One possible solution is to usurp LCK_CONVERT, as it is not used. When the locking_type is 3, the degraded mode flag simply gets dropped and the old ("complete") behavior is exhibited.
2014-07-10 07:56:11 +04:00
activation_mode = arg_str_value(cmd, activationmode_ARG,
activation_mode);
/* complain only if the two arguments conflict */
if (arg_is_set(cmd, partial_ARG) &&
activation: Add "degraded" activation mode Currently, we have two modes of activation, an unnamed nominal mode (which I will refer to as "complete") and "partial" mode. The "complete" mode requires that a volume group be 'complete' - that is, no missing PVs. If there are any missing PVs, no affected LVs are allowed to activate - even RAID LVs which might be able to tolerate a failure. The "partial" mode allows anything to be activated (or at least attempted). If a non-redundant LV is missing a portion of its addressable space due to a device failure, it will be replaced with an error target. RAID LVs will either activate or fail to activate depending on how badly their redundancy is compromised. This patch adds a third option, "degraded" mode. This mode can be selected via the '--activationmode {complete|degraded|partial}' option to lvchange/vgchange. It can also be set in lvm.conf. The "degraded" activation mode allows RAID LVs with a sufficient level of redundancy to activate (e.g. a RAID5 LV with one device failure, a RAID6 with two device failures, or RAID1 with n-1 failures). RAID LVs with too many device failures are not allowed to activate - nor are any non-redundant LVs that may have been affected. This patch also makes the "degraded" mode the default activation mode. The degraded activation mode does not yet work in a cluster. A new cluster lock flag (LCK_DEGRADED_MODE) will need to be created to make that work. Currently, there is limited space for this extra flag and I am looking for possible solutions. One possible solution is to usurp LCK_CONVERT, as it is not used. When the locking_type is 3, the degraded mode flag simply gets dropped and the old ("complete") behavior is exhibited.
2014-07-10 07:56:11 +04:00
strcmp(activation_mode, "partial")) {
log_error("--partial and --activationmode are mutually"
" exclusive arguments");
return EINVALID_CMD_LINE;
}
} else if (arg_is_set(cmd, partial_ARG))
activation: Add "degraded" activation mode Currently, we have two modes of activation, an unnamed nominal mode (which I will refer to as "complete") and "partial" mode. The "complete" mode requires that a volume group be 'complete' - that is, no missing PVs. If there are any missing PVs, no affected LVs are allowed to activate - even RAID LVs which might be able to tolerate a failure. The "partial" mode allows anything to be activated (or at least attempted). If a non-redundant LV is missing a portion of its addressable space due to a device failure, it will be replaced with an error target. RAID LVs will either activate or fail to activate depending on how badly their redundancy is compromised. This patch adds a third option, "degraded" mode. This mode can be selected via the '--activationmode {complete|degraded|partial}' option to lvchange/vgchange. It can also be set in lvm.conf. The "degraded" activation mode allows RAID LVs with a sufficient level of redundancy to activate (e.g. a RAID5 LV with one device failure, a RAID6 with two device failures, or RAID1 with n-1 failures). RAID LVs with too many device failures are not allowed to activate - nor are any non-redundant LVs that may have been affected. This patch also makes the "degraded" mode the default activation mode. The degraded activation mode does not yet work in a cluster. A new cluster lock flag (LCK_DEGRADED_MODE) will need to be created to make that work. Currently, there is limited space for this extra flag and I am looking for possible solutions. One possible solution is to usurp LCK_CONVERT, as it is not used. When the locking_type is 3, the degraded mode flag simply gets dropped and the old ("complete") behavior is exhibited.
2014-07-10 07:56:11 +04:00
activation_mode = "partial";
2004-03-26 15:00:24 +03:00
activation: Add "degraded" activation mode Currently, we have two modes of activation, an unnamed nominal mode (which I will refer to as "complete") and "partial" mode. The "complete" mode requires that a volume group be 'complete' - that is, no missing PVs. If there are any missing PVs, no affected LVs are allowed to activate - even RAID LVs which might be able to tolerate a failure. The "partial" mode allows anything to be activated (or at least attempted). If a non-redundant LV is missing a portion of its addressable space due to a device failure, it will be replaced with an error target. RAID LVs will either activate or fail to activate depending on how badly their redundancy is compromised. This patch adds a third option, "degraded" mode. This mode can be selected via the '--activationmode {complete|degraded|partial}' option to lvchange/vgchange. It can also be set in lvm.conf. The "degraded" activation mode allows RAID LVs with a sufficient level of redundancy to activate (e.g. a RAID5 LV with one device failure, a RAID6 with two device failures, or RAID1 with n-1 failures). RAID LVs with too many device failures are not allowed to activate - nor are any non-redundant LVs that may have been affected. This patch also makes the "degraded" mode the default activation mode. The degraded activation mode does not yet work in a cluster. A new cluster lock flag (LCK_DEGRADED_MODE) will need to be created to make that work. Currently, there is limited space for this extra flag and I am looking for possible solutions. One possible solution is to usurp LCK_CONVERT, as it is not used. When the locking_type is 3, the degraded mode flag simply gets dropped and the old ("complete") behavior is exhibited.
2014-07-10 07:56:11 +04:00
if (!strcmp(activation_mode, "partial")) {
2008-09-19 11:12:45 +04:00
cmd->partial_activation = 1;
log_warn("PARTIAL MODE. Incomplete logical volumes will be processed.");
} else if (!strcmp(activation_mode, "degraded"))
activation: Add "degraded" activation mode Currently, we have two modes of activation, an unnamed nominal mode (which I will refer to as "complete") and "partial" mode. The "complete" mode requires that a volume group be 'complete' - that is, no missing PVs. If there are any missing PVs, no affected LVs are allowed to activate - even RAID LVs which might be able to tolerate a failure. The "partial" mode allows anything to be activated (or at least attempted). If a non-redundant LV is missing a portion of its addressable space due to a device failure, it will be replaced with an error target. RAID LVs will either activate or fail to activate depending on how badly their redundancy is compromised. This patch adds a third option, "degraded" mode. This mode can be selected via the '--activationmode {complete|degraded|partial}' option to lvchange/vgchange. It can also be set in lvm.conf. The "degraded" activation mode allows RAID LVs with a sufficient level of redundancy to activate (e.g. a RAID5 LV with one device failure, a RAID6 with two device failures, or RAID1 with n-1 failures). RAID LVs with too many device failures are not allowed to activate - nor are any non-redundant LVs that may have been affected. This patch also makes the "degraded" mode the default activation mode. The degraded activation mode does not yet work in a cluster. A new cluster lock flag (LCK_DEGRADED_MODE) will need to be created to make that work. Currently, there is limited space for this extra flag and I am looking for possible solutions. One possible solution is to usurp LCK_CONVERT, as it is not used. When the locking_type is 3, the degraded mode flag simply gets dropped and the old ("complete") behavior is exhibited.
2014-07-10 07:56:11 +04:00
cmd->degraded_activation = 1;
else if (strcmp(activation_mode, "complete")) {
activation: Add "degraded" activation mode Currently, we have two modes of activation, an unnamed nominal mode (which I will refer to as "complete") and "partial" mode. The "complete" mode requires that a volume group be 'complete' - that is, no missing PVs. If there are any missing PVs, no affected LVs are allowed to activate - even RAID LVs which might be able to tolerate a failure. The "partial" mode allows anything to be activated (or at least attempted). If a non-redundant LV is missing a portion of its addressable space due to a device failure, it will be replaced with an error target. RAID LVs will either activate or fail to activate depending on how badly their redundancy is compromised. This patch adds a third option, "degraded" mode. This mode can be selected via the '--activationmode {complete|degraded|partial}' option to lvchange/vgchange. It can also be set in lvm.conf. The "degraded" activation mode allows RAID LVs with a sufficient level of redundancy to activate (e.g. a RAID5 LV with one device failure, a RAID6 with two device failures, or RAID1 with n-1 failures). RAID LVs with too many device failures are not allowed to activate - nor are any non-redundant LVs that may have been affected. This patch also makes the "degraded" mode the default activation mode. The degraded activation mode does not yet work in a cluster. A new cluster lock flag (LCK_DEGRADED_MODE) will need to be created to make that work. Currently, there is limited space for this extra flag and I am looking for possible solutions. One possible solution is to usurp LCK_CONVERT, as it is not used. When the locking_type is 3, the degraded mode flag simply gets dropped and the old ("complete") behavior is exhibited.
2014-07-10 07:56:11 +04:00
log_error("Invalid activation mode given.");
return EINVALID_CMD_LINE;
}
2004-03-26 15:00:24 +03:00
cmd->include_foreign_vgs = arg_is_set(cmd, foreign_ARG) ? 1 : 0;
2015-03-05 23:00:44 +03:00
cmd->include_shared_vgs = arg_is_set(cmd, shared_ARG) ? 1 : 0;
cmd->include_historical_lvs = arg_is_set(cmd, history_ARG) ? 1 : 0;
cmd->record_historical_lvs = find_config_tree_bool(cmd, metadata_record_lvs_history_CFG, NULL) ?
(arg_is_set(cmd, nohistory_ARG) ? 0 : 1) : 0;
2015-03-05 23:00:44 +03:00
device usage based on devices file The LVM devices file lists devices that lvm can use. The default file is /etc/lvm/devices/system.devices, and the lvmdevices(8) command is used to add or remove device entries. If the file does not exist, or if lvm.conf includes use_devicesfile=0, then lvm will not use a devices file. When the devices file is in use, the regex filter is not used, and the filter settings in lvm.conf or on the command line are ignored. LVM records devices in the devices file using hardware-specific IDs, such as the WWID, and attempts to use subsystem-specific IDs for virtual device types. These device IDs are also written in the VG metadata. When no hardware or virtual ID is available, lvm falls back using the unstable device name as the device ID. When devnames are used, lvm performs extra scanning to find devices if their devname changes, e.g. after reboot. When proper device IDs are used, an lvm command will not look at devices outside the devices file, but when devnames are used as a fallback, lvm will scan devices outside the devices file to locate PVs on renamed devices. A config setting search_for_devnames can be used to control the scanning for renamed devname entries. Related to the devices file, the new command option --devices <devnames> allows a list of devices to be specified for the command to use, overriding the devices file. The listed devices act as a sort of devices file in terms of limiting which devices lvm will see and use. Devices that are not listed will appear to be missing to the lvm command. Multiple devices files can be kept in /etc/lvm/devices, which allows lvm to be used with different sets of devices, e.g. system devices do not need to be exposed to a specific application, and the application can use lvm on its own set of devices that are not exposed to the system. The option --devicesfile <filename> is used to select the devices file to use with the command. Without the option set, the default system devices file is used. Setting --devicesfile "" causes lvm to not use a devices file. An existing, empty devices file means lvm will see no devices. The new command vgimportdevices adds PVs from a VG to the devices file and updates the VG metadata to include the device IDs. vgimportdevices -a will import all VGs into the system devices file. LVM commands run by dmeventd not use a devices file by default, and will look at all devices on the system. A devices file can be created for dmeventd (/etc/lvm/devices/dmeventd.devices) If this file exists, lvm commands run by dmeventd will use it. Internal implementaion: - device_ids_read - read the devices file . add struct dev_use (du) to cmd->use_devices for each devices file entry - dev_cache_scan - get /dev entries . add struct device (dev) to dev_cache for each device on the system - device_ids_match - match devices file entries to /dev entries . match each du on cmd->use_devices to a dev in dev_cache, using device ID . on match, set du->dev, dev->id, dev->flags MATCHED_USE_ID - label_scan - read lvm headers and metadata from devices . filters are applied, those that do not need data from the device . filter-deviceid skips devs without MATCHED_USE_ID, i.e. skips /dev entries that are not listed in the devices file . read lvm label from dev . filters are applied, those that use data from the device . read lvm metadata from dev . add info/vginfo structs for PVs/VGs (info is "lvmcache") - device_ids_find_renamed_devs - handle devices with unstable devname ID where devname changed . this step only needed when devs do not have proper device IDs, and their dev names change, e.g. after reboot sdb becomes sdc. . detect incorrect match because PVID in the devices file entry does not match the PVID found when the device was read above . undo incorrect match between du and dev above . search system devices for new location of PVID . update devices file with new devnames for PVIDs on renamed devices . label_scan the renamed devs - continue with command processing
2020-06-23 21:25:41 +03:00
if (!(search_mode = find_config_tree_str(cmd, devices_search_for_devnames_CFG, NULL)))
cmd->search_for_devnames = DEFAULT_SEARCH_FOR_DEVNAMES;
else {
if (!strcmp(search_mode, "none") || !strcmp(search_mode, "auto") || !strcmp(search_mode, "all"))
cmd->search_for_devnames = search_mode;
else {
log_warn("WARNING: Ignoring unknown search_for_devnames setting, using %s.", DEFAULT_SEARCH_FOR_DEVNAMES);
device usage based on devices file The LVM devices file lists devices that lvm can use. The default file is /etc/lvm/devices/system.devices, and the lvmdevices(8) command is used to add or remove device entries. If the file does not exist, or if lvm.conf includes use_devicesfile=0, then lvm will not use a devices file. When the devices file is in use, the regex filter is not used, and the filter settings in lvm.conf or on the command line are ignored. LVM records devices in the devices file using hardware-specific IDs, such as the WWID, and attempts to use subsystem-specific IDs for virtual device types. These device IDs are also written in the VG metadata. When no hardware or virtual ID is available, lvm falls back using the unstable device name as the device ID. When devnames are used, lvm performs extra scanning to find devices if their devname changes, e.g. after reboot. When proper device IDs are used, an lvm command will not look at devices outside the devices file, but when devnames are used as a fallback, lvm will scan devices outside the devices file to locate PVs on renamed devices. A config setting search_for_devnames can be used to control the scanning for renamed devname entries. Related to the devices file, the new command option --devices <devnames> allows a list of devices to be specified for the command to use, overriding the devices file. The listed devices act as a sort of devices file in terms of limiting which devices lvm will see and use. Devices that are not listed will appear to be missing to the lvm command. Multiple devices files can be kept in /etc/lvm/devices, which allows lvm to be used with different sets of devices, e.g. system devices do not need to be exposed to a specific application, and the application can use lvm on its own set of devices that are not exposed to the system. The option --devicesfile <filename> is used to select the devices file to use with the command. Without the option set, the default system devices file is used. Setting --devicesfile "" causes lvm to not use a devices file. An existing, empty devices file means lvm will see no devices. The new command vgimportdevices adds PVs from a VG to the devices file and updates the VG metadata to include the device IDs. vgimportdevices -a will import all VGs into the system devices file. LVM commands run by dmeventd not use a devices file by default, and will look at all devices on the system. A devices file can be created for dmeventd (/etc/lvm/devices/dmeventd.devices) If this file exists, lvm commands run by dmeventd will use it. Internal implementaion: - device_ids_read - read the devices file . add struct dev_use (du) to cmd->use_devices for each devices file entry - dev_cache_scan - get /dev entries . add struct device (dev) to dev_cache for each device on the system - device_ids_match - match devices file entries to /dev entries . match each du on cmd->use_devices to a dev in dev_cache, using device ID . on match, set du->dev, dev->id, dev->flags MATCHED_USE_ID - label_scan - read lvm headers and metadata from devices . filters are applied, those that do not need data from the device . filter-deviceid skips devs without MATCHED_USE_ID, i.e. skips /dev entries that are not listed in the devices file . read lvm label from dev . filters are applied, those that use data from the device . read lvm metadata from dev . add info/vginfo structs for PVs/VGs (info is "lvmcache") - device_ids_find_renamed_devs - handle devices with unstable devname ID where devname changed . this step only needed when devs do not have proper device IDs, and their dev names change, e.g. after reboot sdb becomes sdc. . detect incorrect match because PVID in the devices file entry does not match the PVID found when the device was read above . undo incorrect match between du and dev above . search system devices for new location of PVID . update devices file with new devnames for PVIDs on renamed devices . label_scan the renamed devs - continue with command processing
2020-06-23 21:25:41 +03:00
cmd->search_for_devnames = DEFAULT_SEARCH_FOR_DEVNAMES;
}
}
if (arg_is_set(cmd, devicesfile_ARG)) {
const char *devices_file = arg_str_value(cmd, devicesfile_ARG, NULL);
if (devices_file && !strlen(devices_file)) {
cmd->devicesfile = "";
} else if (!devices_file || !validate_name(devices_file)) {
log_error("Invalid devices file name.");
return EINVALID_CMD_LINE;
} else if (!(cmd->devicesfile = dm_pool_strdup(cmd->libmem, devices_file))) {
log_error("Failed to copy devices file name.");
return EINVALID_CMD_LINE;
}
}
dm_list_init(&cmd->deviceslist);
if (arg_is_set(cmd, devices_ARG)) {
if (cmd->devicesfile && strlen(cmd->devicesfile)) {
log_error("A --devices list cannot be used with --devicesfile.");
return EINVALID_CMD_LINE;
}
cmd->enable_devices_list = 1;
if (!_read_devices_list(cmd)) {
log_error("Failed to read --devices args.");
return EINVALID_CMD_LINE;
}
}
2015-03-05 23:00:44 +03:00
/*
* This is set to zero by process_each which wants to print errors
* itself rather than having them printed in vg_read.
*/
cmd->vg_read_print_access_error = 1;
if (arg_is_set(cmd, nosuffix_ARG))
2004-03-26 15:00:24 +03:00
cmd->current_settings.suffix = 0;
if (arg_is_set(cmd, units_ARG))
2004-03-26 15:00:24 +03:00
if (!(cmd->current_settings.unit_factor =
dm_units_to_factor(arg_str_value(cmd, units_ARG, ""),
&cmd->current_settings.unit_type, 1, NULL))) {
2004-03-26 15:00:24 +03:00
log_error("Invalid units specification");
return EINVALID_CMD_LINE;
}
if (arg_is_set(cmd, binary_ARG))
cmd->report_binary_values_as_numeric = 1;
if (arg_is_set(cmd, noudevsync_ARG))
2009-08-04 19:36:13 +04:00
cmd->current_settings.udev_sync = 0;
2004-03-26 15:00:24 +03:00
/* Handle synonyms */
if (!_merge_synonym(cmd, resizable_ARG, resizeable_ARG) ||
!_merge_synonym(cmd, allocation_ARG, allocatable_ARG) ||
!_merge_synonym(cmd, allocation_ARG, resizeable_ARG) ||
!_merge_synonym(cmd, virtualoriginsize_ARG, virtualsize_ARG) ||
!_merge_synonym(cmd, available_ARG, activate_ARG) ||
!_merge_synonym(cmd, raidrebuild_ARG, rebuild_ARG) ||
!_merge_synonym(cmd, raidsyncaction_ARG, syncaction_ARG) ||
!_merge_synonym(cmd, raidwritemostly_ARG, writemostly_ARG) ||
!_merge_synonym(cmd, raidminrecoveryrate_ARG, minrecoveryrate_ARG) ||
!_merge_synonym(cmd, raidmaxrecoveryrate_ARG, maxrecoveryrate_ARG) ||
!_merge_synonym(cmd, raidwritebehind_ARG, writebehind_ARG))
return EINVALID_CMD_LINE;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if ((!strncmp(cmd->name, "pv", 2) &&
!_merge_synonym(cmd, metadatacopies_ARG, pvmetadatacopies_ARG)) ||
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
(!strncmp(cmd->name, "vg", 2) &&
!_merge_synonym(cmd, metadatacopies_ARG, vgmetadatacopies_ARG)))
2004-03-26 15:00:24 +03:00
return EINVALID_CMD_LINE;
/* Zero indicates success */
return 0;
}
static int _process_common_commands(struct cmd_context *cmd)
{
if (arg_is_set(cmd, help_ARG) ||
arg_is_set(cmd, longhelp_ARG) ||
arg_is_set(cmd, help2_ARG)) {
_usage(cmd->name, arg_is_set(cmd, longhelp_ARG), 0);
2004-03-26 15:00:24 +03:00
return ECMD_PROCESSED;
}
if (arg_is_set(cmd, version_ARG)) {
2004-03-26 15:00:24 +03:00
return version(cmd, 0, (char **) NULL);
}
/* Zero indicates it's OK to continue processing this command */
return 0;
}
static void _display_help(void)
{
int i;
log_error("Available lvm commands:");
log_error("Use 'lvm help <command>' for more information");
log_error(" ");
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
for (i = 0; i < _cmdline.num_command_names; i++) {
struct command_name *cname = _cmdline.command_names + i;
2004-03-26 15:00:24 +03:00
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
log_error("%-16.16s%s", cname->name, cname->desc);
2004-03-26 15:00:24 +03:00
}
}
int help(struct cmd_context *cmd __attribute__((unused)), int argc, char **argv)
2004-03-26 15:00:24 +03:00
{
int ret = ECMD_PROCESSED;
2004-03-26 15:00:24 +03:00
if (!argc)
_display_help();
else if (argc == 1 && !strcmp(argv[0], "all"))
_usage_all();
2004-03-26 15:00:24 +03:00
else {
int i;
for (i = 0; i < argc; i++)
if (!_usage(argv[i], 0, 0))
ret = EINVALID_CMD_LINE;
2004-03-26 15:00:24 +03:00
}
return ret;
2004-03-26 15:00:24 +03:00
}
static void _apply_current_settings(struct cmd_context *cmd)
2004-03-26 15:00:24 +03:00
{
_apply_current_output_settings(cmd);
2004-03-26 15:00:24 +03:00
init_test(cmd->current_settings.test);
init_mirror_in_sync(0);
init_dmeventd_monitor(DEFAULT_DMEVENTD_MONITOR);
2004-03-26 15:00:24 +03:00
init_msg_prefix(cmd->default_settings.msg_prefix);
archive_enable(cmd, cmd->current_settings.archive);
backup_enable(cmd, cmd->current_settings.backup);
2004-03-26 15:00:24 +03:00
set_activation(cmd->current_settings.activation, cmd->metadata_read_only);
2004-03-26 15:00:24 +03:00
cmd->fmt = get_format_by_name(cmd, arg_str_value(cmd, metadatatype_ARG,
cmd->current_settings.fmt_name));
cmd->handles_missing_pvs = 0;
2004-03-26 15:00:24 +03:00
}
2009-07-13 23:49:48 +04:00
static const char *_copy_command_line(struct cmd_context *cmd, int argc, char **argv)
2004-03-26 15:00:24 +03:00
{
int i, space;
2004-03-26 15:00:24 +03:00
/*
* Build up the complete command line, used as a
* description for backups.
*/
if (!dm_pool_begin_object(cmd->mem, 128))
goto_bad;
2004-03-26 15:00:24 +03:00
for (i = 0; i < argc; i++) {
space = strchr(argv[i], ' ') ? 1 : 0;
if (space && !dm_pool_grow_object(cmd->mem, "'", 1))
goto_bad;
if (!dm_pool_grow_object(cmd->mem, argv[i], strlen(argv[i])))
goto_bad;
2004-03-26 15:00:24 +03:00
if (space && !dm_pool_grow_object(cmd->mem, "'", 1))
goto_bad;
2004-03-26 15:00:24 +03:00
if (i < (argc - 1))
if (!dm_pool_grow_object(cmd->mem, " ", 1))
goto_bad;
2004-03-26 15:00:24 +03:00
}
/*
* Terminate.
*/
if (!dm_pool_grow_object(cmd->mem, "\0", 1))
goto_bad;
2004-03-26 15:00:24 +03:00
return dm_pool_end_object(cmd->mem);
2004-03-26 15:00:24 +03:00
bad:
log_error("Couldn't copy command line.");
dm_pool_abandon_object(cmd->mem);
2004-03-26 15:00:24 +03:00
return NULL;
}
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
static int _prepare_profiles(struct cmd_context *cmd)
2004-03-26 15:00:24 +03:00
{
static const char COMMAND_PROFILE_ENV_VAR_NAME[] = "LVM_COMMAND_PROFILE";
static const char _cmd_profile_arg_preferred_over_env_var_msg[] = "Giving "
"preference to command profile specified on command "
"line over the one specified via environment variable.";
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
static const char _failed_to_add_profile_msg[] = "Failed to add %s %s.";
static const char _failed_to_apply_profile_msg[] = "Failed to apply %s %s.";
static const char _command_profile_source_name[] = "command profile";
static const char _metadata_profile_source_name[] = "metadata profile";
static const char _setting_global_profile_msg[] = "Setting global %s \"%s\".";
const char *env_cmd_profile_name = NULL;
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
const char *name;
struct profile *profile;
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
config_source_t source;
const char *source_name;
/* Check whether default global command profile is set via env. var. */
if ((env_cmd_profile_name = getenv(COMMAND_PROFILE_ENV_VAR_NAME))) {
if (!*env_cmd_profile_name)
env_cmd_profile_name = NULL;
else
log_debug("Command profile '%s' requested via "
"environment variable.",
env_cmd_profile_name);
}
if (!arg_is_set(cmd, profile_ARG) &&
!arg_is_set(cmd, commandprofile_ARG) &&
!arg_is_set(cmd, metadataprofile_ARG) &&
!env_cmd_profile_name)
/* nothing to do */
return 1;
if (arg_is_set(cmd, profile_ARG)) {
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
/*
* If --profile is used with dumpconfig, it's used
* to dump the profile without the profile being applied.
*/
if (!strcmp(cmd->command->name, "dumpconfig") ||
!strcmp(cmd->command->name, "lvmconfig") ||
!strcmp(cmd->command->name, "config"))
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
return 1;
/*
* If --profile is used with lvcreate/lvchange/vgchange,
* it's recognized as shortcut to --metadataprofile.
* The --commandprofile is assumed otherwise.
*/
if (!strcmp(cmd->command->name, "lvcreate") ||
!strcmp(cmd->command->name, "lvconvert") ||
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
!strcmp(cmd->command->name, "vgcreate") ||
!strcmp(cmd->command->name, "lvchange") ||
!strcmp(cmd->command->name, "vgchange")) {
if (arg_is_set(cmd, metadataprofile_ARG)) {
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
log_error("Only one of --profile or "
" --metadataprofile allowed.");
return 0;
}
source = CONFIG_PROFILE_METADATA;
source_name = _metadata_profile_source_name;
}
else {
if (arg_is_set(cmd, commandprofile_ARG)) {
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
log_error("Only one of --profile or "
"--commandprofile allowed.");
return 0;
}
/*
* Prefer command profile specified on command
* line over the profile specified via
* COMMAND_PROFILE_ENV_VAR_NAME env. var.
*/
if (env_cmd_profile_name) {
log_debug(_cmd_profile_arg_preferred_over_env_var_msg);
env_cmd_profile_name = NULL;
}
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
source = CONFIG_PROFILE_COMMAND;
source_name = _command_profile_source_name;
}
name = arg_str_value(cmd, profile_ARG, NULL);
if (!(profile = add_profile(cmd, name, source))) {
log_error(_failed_to_add_profile_msg, source_name, name);
return 0;
}
if (source == CONFIG_PROFILE_COMMAND) {
log_debug(_setting_global_profile_msg, _command_profile_source_name, profile->name);
cmd->profile_params->global_command_profile = profile;
} else if (source == CONFIG_PROFILE_METADATA) {
log_debug(_setting_global_profile_msg, _metadata_profile_source_name, profile->name);
/* This profile will override any VG/LV-based profile if present */
cmd->profile_params->global_metadata_profile = profile;
}
remove_config_tree_by_source(cmd, source);
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
if (!override_config_tree_from_profile(cmd, profile)) {
log_error(_failed_to_apply_profile_msg, source_name, name);
return 0;
}
}
if (arg_is_set(cmd, commandprofile_ARG) || env_cmd_profile_name) {
if (arg_is_set(cmd, commandprofile_ARG)) {
/*
* Prefer command profile specified on command
* line over the profile specified via
* COMMAND_PROFILE_ENV_VAR_NAME env. var.
*/
if (env_cmd_profile_name)
log_debug(_cmd_profile_arg_preferred_over_env_var_msg);
name = arg_str_value(cmd, commandprofile_ARG, NULL);
} else
name = env_cmd_profile_name;
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
source_name = _command_profile_source_name;
if (!(profile = add_profile(cmd, name, CONFIG_PROFILE_COMMAND))) {
log_error(_failed_to_add_profile_msg, source_name, name);
return 0;
}
remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
if (!override_config_tree_from_profile(cmd, profile)) {
log_error(_failed_to_apply_profile_msg, source_name, name);
return 0;
}
log_debug(_setting_global_profile_msg, _command_profile_source_name, profile->name);
cmd->profile_params->global_command_profile = profile;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (!cmd->opt_arg_values)
cmd->profile_params->shell_profile = profile;
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
}
if (arg_is_set(cmd, metadataprofile_ARG)) {
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
name = arg_str_value(cmd, metadataprofile_ARG, NULL);
source_name = _metadata_profile_source_name;
if (!(profile = add_profile(cmd, name, CONFIG_PROFILE_METADATA))) {
log_error(_failed_to_add_profile_msg, source_name, name);
return 0;
}
remove_config_tree_by_source(cmd, CONFIG_PROFILE_METADATA);
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
if (!override_config_tree_from_profile(cmd, profile)) {
log_error(_failed_to_apply_profile_msg, source_name, name);
return 0;
}
log_debug(_setting_global_profile_msg, _metadata_profile_source_name, profile->name);
cmd->profile_params->global_metadata_profile = profile;
}
if (!process_profilable_config(cmd))
return_0;
return 1;
}
2015-03-05 23:00:44 +03:00
static int _init_lvmlockd(struct cmd_context *cmd)
{
const char *lvmlockd_socket;
int use_lvmlockd = find_config_tree_bool(cmd, global_use_lvmlockd_CFG, NULL);
if (cmd->command->command_enum == pvscan_cache_CMD) {
/* pvscan cache ignores shared vgs, it only activates local vgs. */
if (use_lvmlockd)
log_debug("Ignore lvmlockd for pvscan cache.");
return 1;
}
/*
* Think about when/how to enable hints with lvmlockd.
*/
if (use_lvmlockd)
cmd->enable_hints = 0;
if (use_lvmlockd && arg_is_set(cmd, nolocking_ARG)) {
/* --nolocking is only allowed with vgs/lvs/pvs commands */
cmd->lockd_gl_disable = 1;
cmd->lockd_vg_disable = 1;
cmd->lockd_lv_disable = 1;
return 1;
}
if (use_lvmlockd && arg_is_set(cmd, lockopt_ARG)) {
const char *opts = arg_str_value(cmd, lockopt_ARG, "");
if (strstr(opts, "skiplv")) {
log_warn("WARNING: skipping LV lock in lvmlockd.");
cmd->lockd_lv_disable = 1;
}
if (strstr(opts, "skipvg")) {
log_warn("WARNING: skipping VG lock in lvmlockd.");
cmd->lockd_vg_disable = 1;
}
if (strstr(opts, "skipgl")) {
log_warn("WARNING: skipping global lock in lvmlockd.");
cmd->lockd_gl_disable = 1;
}
}
2015-03-05 23:00:44 +03:00
lvmlockd_disconnect(); /* start over when tool context is refreshed */
lvmlockd_socket = getenv("LVM_LVMLOCKD_SOCKET");
if (!lvmlockd_socket)
lvmlockd_socket = DEFAULT_RUN_DIR "/lvmlockd.socket";
lvmlockd_set_socket(lvmlockd_socket);
lvmlockd_set_use(use_lvmlockd);
if (use_lvmlockd) {
lvmlockd_init(cmd);
lvmlockd_connect();
}
return 1;
}
/*
* md_component_check full: always set use_full_md_check
* which causes filter-md to read the start+end of every
* device on the system (this could be optimized to only
* read the end of PVs.)
*
* md_component_check start: the end of devices will
* not generally be read to check for an md superblock
* (lvm may still scan for end-of-device md superblocks
* if it knows that some exists.)
*
* md_component_check auto: lvm will use some built-in
* heuristics to decide when it should scan the end of
* devices to look for md superblocks, e.g. commands
* like pvcreate that could clobber a component, or if
* udev info is not available and hints are not available.
*/
static void _init_md_checks(struct cmd_context *cmd)
{
const char *md_check;
cmd->md_component_detection = find_config_tree_bool(cmd, devices_md_component_detection_CFG, NULL);
md_check = find_config_tree_str(cmd, devices_md_component_checks_CFG, NULL);
if (!md_check)
cmd->md_component_checks = "auto";
else if (!strcmp(md_check, "auto") ||
!strcmp(md_check, "start") ||
!strcmp(md_check, "full"))
cmd->md_component_checks = md_check;
else {
log_warn("WARNING: Ignoring unknown md_component_checks setting, using auto.");
cmd->md_component_checks = "auto";
}
if (!strcmp(cmd->md_component_checks, "full"))
cmd->use_full_md_check = 1;
/* use_full_md_check can also be set later */
log_debug("Using md_component_checks %s use_full_md_check %d",
cmd->md_component_checks, cmd->use_full_md_check);
}
static int _cmd_no_meta_proc(struct cmd_context *cmd)
{
return cmd->cname->flags & NO_METADATA_PROCESSING;
}
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
int lvm_run_command(struct cmd_context *cmd, int argc, char **argv)
{
struct dm_config_tree *config_string_cft, *config_profile_command_cft, *config_profile_metadata_cft;
2004-03-26 15:00:24 +03:00
int ret = 0;
int locking_type;
Rework lock-override options and locking_type settings The last commit related to this was incomplete: "Implement lock-override options without locking type" This is further reworking and reduction of the locking.[ch] layer which handled all clustering, but is now only used for file locking. The "locking types" that this layer implemented were removed previously, leaving only the standard file locking. (Some cluster-related artifacts remain to be cleared out later.) Command options to override or modify locking behavior are reimplemented here without using the locking types. Also, deprecated locking_type values are recognized, and implemented as if one of the equivalent override options was set. Options that override file locking are: . --nolocking disables all file locking. . --readonly grants read lock requests without actually taking a file lock, and refuses write lock requests. . --ignorelockingfailure tries to set up file locks and uses them normally if possible. When not possible, it behaves like --readonly, but allows activation. . --sysinit is the same as ignorelockingfailure. . global/metadata_read_only acquires actual read file locks, and refuses write lock requests. (Some of these options could probably be deprecated because they were added as workarounds to various locking_type behaviors that are now deprecated.) The locking_type setting now has one valid value: 1 which refers to standard file locking. Configs that contain deprecated values are recognized and still work in largely the same way: . 0 disabled all locking, now implemented like --nolocking is set. Allow the nolocking option in all commands. . 1 is the normal file locking setting and is unchanged. . 2 was for external locking which was not used, and reverts to normal file locking. . 3 was for cluster/clvm. This reverts to normal file locking, and prints messages about lvmlockd. . 4 was equivalent to readonly, now implemented like --readonly is set. . 5 disabled all locking, now implemented like --nolocking is set.
2018-06-07 23:33:02 +03:00
int readonly = 0;
int sysinit = 0;
int monitoring;
char *arg_new, *arg;
int i;
int skip_hyphens;
int refresh_done = 0;
int io;
2004-03-26 15:00:24 +03:00
/* Avoid excessive access to /etc/localtime and set TZ variable for glibc
* so it does not need to check /etc/localtime everytime that needs that info */
if (!getenv("TZ"))
setenv("TZ", ":/etc/localtime", 0);
2008-06-06 23:28:35 +04:00
init_error_message_produced(0);
/* each command should start out with sigint flag cleared */
sigint_clear();
if (!(cmd->name = dm_pool_strdup(cmd->mem, dm_basename(argv[0])))) {
log_error("Failed to strdup command basename.");
return ECMD_FAILED;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
set_cmd_name(cmd->name);
init_log_command(find_config_tree_bool(cmd, log_command_names_CFG, NULL), 0);
/* eliminate '-' from all options starting with -- */
for (i = 1; i < argc; i++) {
arg = argv[i];
if (*arg++ != '-' || *arg++ != '-')
continue;
/* If we reach "--" then stop. */
if (!*arg)
break;
arg_new = arg;
skip_hyphens = 1;
while (*arg) {
/* If we encounter '=', stop any further hyphen removal. */
if (*arg == '=')
skip_hyphens = 0;
/* Do we need to keep the next character? */
if (*arg != '-' || !skip_hyphens) {
if (arg_new != arg)
*arg_new = *arg;
++arg_new;
}
arg++;
}
/* Terminate a shortened arg */
if (arg_new != arg)
*arg_new = '\0';
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/* The cmd_line string is only used for logging, not processing. */
if (!(cmd->cmd_line = _copy_command_line(cmd, argc, argv)))
return_ECMD_FAILED;
2004-03-26 15:00:24 +03:00
/* Look up command - will be NULL if not recognised */
if (!(cmd->cname = find_command_name(cmd->name)))
return ENO_SUCH_CMD;
cmd->get_vgname_from_options = (cmd->cname->flags & GET_VGNAME_FROM_OPTIONS) ? 1 : 0;
2004-03-26 15:00:24 +03:00
if (!_process_command_line(cmd, &argc, &argv)) {
log_error("Error during parsing of command line.");
2004-03-26 15:00:24 +03:00
return EINVALID_CMD_LINE;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* Now we have the command line args, set up any known output logging
* options immediately.
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
*/
_reset_current_settings_to_default(cmd);
_get_current_output_settings_from_args(cmd);
_apply_current_output_settings(cmd);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
2021-02-12 19:51:41 +03:00
log_debug("Version: %s", LVM_VERSION);
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
log_debug("Parsing: %s", cmd->cmd_line);
if (!(cmd->command = _find_command(cmd, cmd->name, &argc, argv)))
return EINVALID_CMD_LINE;
/* avoid this by letting lib code use cmd->command */
cmd->command_enum = cmd->command->command_enum;
/*
* If option --foo is set which is listed in IO (ignore option) in
* command-lines.in, then unset foo. Commands won't usually use an
* ignored option, but there can be shared code that checks for --foo,
* and should not find it to be set.
*/
for (io = 0; io < cmd->command->io_count; io++) {
int opt = cmd->command->ignore_opt_args[io].opt;
if (arg_is_set(cmd, opt)) {
log_debug("Ignore opt %d", opt);
cmd->opt_arg_values[opt].count = 0;
}
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* Remaining position args after command name and --options are removed.
*/
cmd->position_argc = argc;
cmd->position_argv = argv;
if (arg_is_set(cmd, config_ARG))
if (!override_config_tree_from_string(cmd, arg_str_value(cmd, config_ARG, ""))) {
ret = EINVALID_CMD_LINE;
goto_out;
}
if (arg_is_set(cmd, config_ARG) || !cmd->initialized.config || config_files_changed(cmd)) {
2004-03-26 15:00:24 +03:00
/* Reinitialise various settings inc. logging, filters */
if (!refresh_toolcontext(cmd)) {
if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
dm_config_destroy(config_string_cft);
2004-03-26 15:00:24 +03:00
log_error("Updated config file invalid. Aborting.");
return ECMD_FAILED;
}
refresh_done = 1;
2004-03-26 15:00:24 +03:00
}
if (!_prepare_profiles(cmd))
return_ECMD_FAILED;
if (!cmd->initialized.connections && !_cmd_no_meta_proc(cmd) && !init_connections(cmd))
return_ECMD_FAILED;
if (!cmd->initialized.filters && !_cmd_no_meta_proc(cmd) &&
!init_filters(cmd, !refresh_done))
return_ECMD_FAILED;
cmd->metadata_read_only = arg_is_set(cmd, readonly_ARG);
cmd->is_activating = (cmd->command->command_enum == vgchange_activate_CMD) ||
(cmd->command->command_enum == lvchange_activate_CMD);
cmd->wipe_outdated_pvs = 0;
Rework lock-override options and locking_type settings The last commit related to this was incomplete: "Implement lock-override options without locking type" This is further reworking and reduction of the locking.[ch] layer which handled all clustering, but is now only used for file locking. The "locking types" that this layer implemented were removed previously, leaving only the standard file locking. (Some cluster-related artifacts remain to be cleared out later.) Command options to override or modify locking behavior are reimplemented here without using the locking types. Also, deprecated locking_type values are recognized, and implemented as if one of the equivalent override options was set. Options that override file locking are: . --nolocking disables all file locking. . --readonly grants read lock requests without actually taking a file lock, and refuses write lock requests. . --ignorelockingfailure tries to set up file locks and uses them normally if possible. When not possible, it behaves like --readonly, but allows activation. . --sysinit is the same as ignorelockingfailure. . global/metadata_read_only acquires actual read file locks, and refuses write lock requests. (Some of these options could probably be deprecated because they were added as workarounds to various locking_type behaviors that are now deprecated.) The locking_type setting now has one valid value: 1 which refers to standard file locking. Configs that contain deprecated values are recognized and still work in largely the same way: . 0 disabled all locking, now implemented like --nolocking is set. Allow the nolocking option in all commands. . 1 is the normal file locking setting and is unchanged. . 2 was for external locking which was not used, and reverts to normal file locking. . 3 was for cluster/clvm. This reverts to normal file locking, and prints messages about lvmlockd. . 4 was equivalent to readonly, now implemented like --readonly is set. . 5 disabled all locking, now implemented like --nolocking is set.
2018-06-07 23:33:02 +03:00
/*
* Now that all configs, profiles and command lines args are available,
* freshly calculate and apply all settings. Specific command line
* options take precedence over config files (which include --config as
* that is treated like a config file).
*/
_reset_current_settings_to_default(cmd);
if ((ret = _get_current_settings(cmd)))
goto_out;
_apply_current_settings(cmd);
if (cmd->degraded_activation)
log_debug("DEGRADED MODE. Incomplete RAID LVs will be processed.");
2004-03-26 15:00:24 +03:00
if (!get_activation_monitoring_mode(cmd, &monitoring))
goto_out;
init_dmeventd_monitor(monitoring);
log_debug("Processing command: %s", cmd->cmd_line);
log_debug("Command pid: %d", getpid());
log_debug("System ID: %s", cmd->system_id ? : "");
#ifdef O_DIRECT_SUPPORT
log_debug("O_DIRECT will be used");
#endif
if ((ret = _process_common_commands(cmd))) {
if (ret != ECMD_PROCESSED)
stack;
goto out;
}
2004-03-26 15:00:24 +03:00
if (cmd->metadata_read_only &&
!(cmd->cname->flags & PERMITTED_READ_ONLY)) {
log_error("%s: Command not permitted while global/metadata_read_only "
"is set.", cmd->cmd_line);
goto out;
}
cmd->ignorelockingfailure = arg_is_set(cmd, ignorelockingfailure_ARG);
cmd->nolocking = arg_is_set(cmd, nolocking_ARG);
if (_cmd_no_meta_proc(cmd))
cmd->nolocking = 1;
Rework lock-override options and locking_type settings The last commit related to this was incomplete: "Implement lock-override options without locking type" This is further reworking and reduction of the locking.[ch] layer which handled all clustering, but is now only used for file locking. The "locking types" that this layer implemented were removed previously, leaving only the standard file locking. (Some cluster-related artifacts remain to be cleared out later.) Command options to override or modify locking behavior are reimplemented here without using the locking types. Also, deprecated locking_type values are recognized, and implemented as if one of the equivalent override options was set. Options that override file locking are: . --nolocking disables all file locking. . --readonly grants read lock requests without actually taking a file lock, and refuses write lock requests. . --ignorelockingfailure tries to set up file locks and uses them normally if possible. When not possible, it behaves like --readonly, but allows activation. . --sysinit is the same as ignorelockingfailure. . global/metadata_read_only acquires actual read file locks, and refuses write lock requests. (Some of these options could probably be deprecated because they were added as workarounds to various locking_type behaviors that are now deprecated.) The locking_type setting now has one valid value: 1 which refers to standard file locking. Configs that contain deprecated values are recognized and still work in largely the same way: . 0 disabled all locking, now implemented like --nolocking is set. Allow the nolocking option in all commands. . 1 is the normal file locking setting and is unchanged. . 2 was for external locking which was not used, and reverts to normal file locking. . 3 was for cluster/clvm. This reverts to normal file locking, and prints messages about lvmlockd. . 4 was equivalent to readonly, now implemented like --readonly is set. . 5 disabled all locking, now implemented like --nolocking is set.
2018-06-07 23:33:02 +03:00
/* Defaults to 1 if not set. */
locking_type = find_config_tree_int(cmd, global_locking_type_CFG, NULL);
if (locking_type == 3)
Rework lock-override options and locking_type settings The last commit related to this was incomplete: "Implement lock-override options without locking type" This is further reworking and reduction of the locking.[ch] layer which handled all clustering, but is now only used for file locking. The "locking types" that this layer implemented were removed previously, leaving only the standard file locking. (Some cluster-related artifacts remain to be cleared out later.) Command options to override or modify locking behavior are reimplemented here without using the locking types. Also, deprecated locking_type values are recognized, and implemented as if one of the equivalent override options was set. Options that override file locking are: . --nolocking disables all file locking. . --readonly grants read lock requests without actually taking a file lock, and refuses write lock requests. . --ignorelockingfailure tries to set up file locks and uses them normally if possible. When not possible, it behaves like --readonly, but allows activation. . --sysinit is the same as ignorelockingfailure. . global/metadata_read_only acquires actual read file locks, and refuses write lock requests. (Some of these options could probably be deprecated because they were added as workarounds to various locking_type behaviors that are now deprecated.) The locking_type setting now has one valid value: 1 which refers to standard file locking. Configs that contain deprecated values are recognized and still work in largely the same way: . 0 disabled all locking, now implemented like --nolocking is set. Allow the nolocking option in all commands. . 1 is the normal file locking setting and is unchanged. . 2 was for external locking which was not used, and reverts to normal file locking. . 3 was for cluster/clvm. This reverts to normal file locking, and prints messages about lvmlockd. . 4 was equivalent to readonly, now implemented like --readonly is set. . 5 disabled all locking, now implemented like --nolocking is set.
2018-06-07 23:33:02 +03:00
log_warn("WARNING: see lvmlockd(8) for information on using cluster/clvm VGs.");
Rework lock-override options and locking_type settings The last commit related to this was incomplete: "Implement lock-override options without locking type" This is further reworking and reduction of the locking.[ch] layer which handled all clustering, but is now only used for file locking. The "locking types" that this layer implemented were removed previously, leaving only the standard file locking. (Some cluster-related artifacts remain to be cleared out later.) Command options to override or modify locking behavior are reimplemented here without using the locking types. Also, deprecated locking_type values are recognized, and implemented as if one of the equivalent override options was set. Options that override file locking are: . --nolocking disables all file locking. . --readonly grants read lock requests without actually taking a file lock, and refuses write lock requests. . --ignorelockingfailure tries to set up file locks and uses them normally if possible. When not possible, it behaves like --readonly, but allows activation. . --sysinit is the same as ignorelockingfailure. . global/metadata_read_only acquires actual read file locks, and refuses write lock requests. (Some of these options could probably be deprecated because they were added as workarounds to various locking_type behaviors that are now deprecated.) The locking_type setting now has one valid value: 1 which refers to standard file locking. Configs that contain deprecated values are recognized and still work in largely the same way: . 0 disabled all locking, now implemented like --nolocking is set. Allow the nolocking option in all commands. . 1 is the normal file locking setting and is unchanged. . 2 was for external locking which was not used, and reverts to normal file locking. . 3 was for cluster/clvm. This reverts to normal file locking, and prints messages about lvmlockd. . 4 was equivalent to readonly, now implemented like --readonly is set. . 5 disabled all locking, now implemented like --nolocking is set.
2018-06-07 23:33:02 +03:00
if ((locking_type == 0) || (locking_type == 5)) {
log_warn("WARNING: locking_type (%d) is deprecated, using --nolocking.", locking_type);
cmd->nolocking = 1;
Rework lock-override options and locking_type settings The last commit related to this was incomplete: "Implement lock-override options without locking type" This is further reworking and reduction of the locking.[ch] layer which handled all clustering, but is now only used for file locking. The "locking types" that this layer implemented were removed previously, leaving only the standard file locking. (Some cluster-related artifacts remain to be cleared out later.) Command options to override or modify locking behavior are reimplemented here without using the locking types. Also, deprecated locking_type values are recognized, and implemented as if one of the equivalent override options was set. Options that override file locking are: . --nolocking disables all file locking. . --readonly grants read lock requests without actually taking a file lock, and refuses write lock requests. . --ignorelockingfailure tries to set up file locks and uses them normally if possible. When not possible, it behaves like --readonly, but allows activation. . --sysinit is the same as ignorelockingfailure. . global/metadata_read_only acquires actual read file locks, and refuses write lock requests. (Some of these options could probably be deprecated because they were added as workarounds to various locking_type behaviors that are now deprecated.) The locking_type setting now has one valid value: 1 which refers to standard file locking. Configs that contain deprecated values are recognized and still work in largely the same way: . 0 disabled all locking, now implemented like --nolocking is set. Allow the nolocking option in all commands. . 1 is the normal file locking setting and is unchanged. . 2 was for external locking which was not used, and reverts to normal file locking. . 3 was for cluster/clvm. This reverts to normal file locking, and prints messages about lvmlockd. . 4 was equivalent to readonly, now implemented like --readonly is set. . 5 disabled all locking, now implemented like --nolocking is set.
2018-06-07 23:33:02 +03:00
} else if (locking_type == 4) {
log_warn("WARNING: locking_type (%d) is deprecated, using --sysinit --readonly.", locking_type);
sysinit = 1;
Rework lock-override options and locking_type settings The last commit related to this was incomplete: "Implement lock-override options without locking type" This is further reworking and reduction of the locking.[ch] layer which handled all clustering, but is now only used for file locking. The "locking types" that this layer implemented were removed previously, leaving only the standard file locking. (Some cluster-related artifacts remain to be cleared out later.) Command options to override or modify locking behavior are reimplemented here without using the locking types. Also, deprecated locking_type values are recognized, and implemented as if one of the equivalent override options was set. Options that override file locking are: . --nolocking disables all file locking. . --readonly grants read lock requests without actually taking a file lock, and refuses write lock requests. . --ignorelockingfailure tries to set up file locks and uses them normally if possible. When not possible, it behaves like --readonly, but allows activation. . --sysinit is the same as ignorelockingfailure. . global/metadata_read_only acquires actual read file locks, and refuses write lock requests. (Some of these options could probably be deprecated because they were added as workarounds to various locking_type behaviors that are now deprecated.) The locking_type setting now has one valid value: 1 which refers to standard file locking. Configs that contain deprecated values are recognized and still work in largely the same way: . 0 disabled all locking, now implemented like --nolocking is set. Allow the nolocking option in all commands. . 1 is the normal file locking setting and is unchanged. . 2 was for external locking which was not used, and reverts to normal file locking. . 3 was for cluster/clvm. This reverts to normal file locking, and prints messages about lvmlockd. . 4 was equivalent to readonly, now implemented like --readonly is set. . 5 disabled all locking, now implemented like --nolocking is set.
2018-06-07 23:33:02 +03:00
readonly = 1;
} else if (locking_type != 1) {
log_warn("WARNING: locking_type (%d) is deprecated, using file locking.", locking_type);
}
device usage based on devices file The LVM devices file lists devices that lvm can use. The default file is /etc/lvm/devices/system.devices, and the lvmdevices(8) command is used to add or remove device entries. If the file does not exist, or if lvm.conf includes use_devicesfile=0, then lvm will not use a devices file. When the devices file is in use, the regex filter is not used, and the filter settings in lvm.conf or on the command line are ignored. LVM records devices in the devices file using hardware-specific IDs, such as the WWID, and attempts to use subsystem-specific IDs for virtual device types. These device IDs are also written in the VG metadata. When no hardware or virtual ID is available, lvm falls back using the unstable device name as the device ID. When devnames are used, lvm performs extra scanning to find devices if their devname changes, e.g. after reboot. When proper device IDs are used, an lvm command will not look at devices outside the devices file, but when devnames are used as a fallback, lvm will scan devices outside the devices file to locate PVs on renamed devices. A config setting search_for_devnames can be used to control the scanning for renamed devname entries. Related to the devices file, the new command option --devices <devnames> allows a list of devices to be specified for the command to use, overriding the devices file. The listed devices act as a sort of devices file in terms of limiting which devices lvm will see and use. Devices that are not listed will appear to be missing to the lvm command. Multiple devices files can be kept in /etc/lvm/devices, which allows lvm to be used with different sets of devices, e.g. system devices do not need to be exposed to a specific application, and the application can use lvm on its own set of devices that are not exposed to the system. The option --devicesfile <filename> is used to select the devices file to use with the command. Without the option set, the default system devices file is used. Setting --devicesfile "" causes lvm to not use a devices file. An existing, empty devices file means lvm will see no devices. The new command vgimportdevices adds PVs from a VG to the devices file and updates the VG metadata to include the device IDs. vgimportdevices -a will import all VGs into the system devices file. LVM commands run by dmeventd not use a devices file by default, and will look at all devices on the system. A devices file can be created for dmeventd (/etc/lvm/devices/dmeventd.devices) If this file exists, lvm commands run by dmeventd will use it. Internal implementaion: - device_ids_read - read the devices file . add struct dev_use (du) to cmd->use_devices for each devices file entry - dev_cache_scan - get /dev entries . add struct device (dev) to dev_cache for each device on the system - device_ids_match - match devices file entries to /dev entries . match each du on cmd->use_devices to a dev in dev_cache, using device ID . on match, set du->dev, dev->id, dev->flags MATCHED_USE_ID - label_scan - read lvm headers and metadata from devices . filters are applied, those that do not need data from the device . filter-deviceid skips devs without MATCHED_USE_ID, i.e. skips /dev entries that are not listed in the devices file . read lvm label from dev . filters are applied, those that use data from the device . read lvm metadata from dev . add info/vginfo structs for PVs/VGs (info is "lvmcache") - device_ids_find_renamed_devs - handle devices with unstable devname ID where devname changed . this step only needed when devs do not have proper device IDs, and their dev names change, e.g. after reboot sdb becomes sdc. . detect incorrect match because PVID in the devices file entry does not match the PVID found when the device was read above . undo incorrect match between du and dev above . search system devices for new location of PVID . update devices file with new devnames for PVIDs on renamed devices . label_scan the renamed devs - continue with command processing
2020-06-23 21:25:41 +03:00
if ((cmd->sysinit = arg_is_set(cmd, sysinit_ARG)))
sysinit = 1;
Rework lock-override options and locking_type settings The last commit related to this was incomplete: "Implement lock-override options without locking type" This is further reworking and reduction of the locking.[ch] layer which handled all clustering, but is now only used for file locking. The "locking types" that this layer implemented were removed previously, leaving only the standard file locking. (Some cluster-related artifacts remain to be cleared out later.) Command options to override or modify locking behavior are reimplemented here without using the locking types. Also, deprecated locking_type values are recognized, and implemented as if one of the equivalent override options was set. Options that override file locking are: . --nolocking disables all file locking. . --readonly grants read lock requests without actually taking a file lock, and refuses write lock requests. . --ignorelockingfailure tries to set up file locks and uses them normally if possible. When not possible, it behaves like --readonly, but allows activation. . --sysinit is the same as ignorelockingfailure. . global/metadata_read_only acquires actual read file locks, and refuses write lock requests. (Some of these options could probably be deprecated because they were added as workarounds to various locking_type behaviors that are now deprecated.) The locking_type setting now has one valid value: 1 which refers to standard file locking. Configs that contain deprecated values are recognized and still work in largely the same way: . 0 disabled all locking, now implemented like --nolocking is set. Allow the nolocking option in all commands. . 1 is the normal file locking setting and is unchanged. . 2 was for external locking which was not used, and reverts to normal file locking. . 3 was for cluster/clvm. This reverts to normal file locking, and prints messages about lvmlockd. . 4 was equivalent to readonly, now implemented like --readonly is set. . 5 disabled all locking, now implemented like --nolocking is set.
2018-06-07 23:33:02 +03:00
if (arg_is_set(cmd, readonly_ARG))
readonly = 1;
if (!cmd->nolocking) {
if (!init_locking(cmd, sysinit, readonly, cmd->ignorelockingfailure)) {
ret = ECMD_FAILED;
goto_out;
}
2004-03-26 15:00:24 +03:00
}
_init_md_checks(cmd);
devices: rework libudev usage related to config settings: obtain_device_info_from_udev (controls if lvm gets a list of devices from readdir /dev or from libudev) external_device_info_source (controls if lvm asks libudev for device information) . Make the obtain_device_list_from_udev setting affect only the choice of readdir /dev vs libudev. The setting no longer controls if udev is used for device type checks. . Change obtain_device_list_from_udev default to 0. This helps avoid boot timeouts due to slow libudev queries, avoids reported failures from udev_enumerate_scan_devices, and avoids delays from "device not initialized in udev database" errors. Even without errors, for a system booting with 1024 PVs, lvm2-pvscan times improve from about 100 sec to 15 sec, and the pvscan command from about 64 sec to about 4 sec. . For external_device_info_source="none", remove all libudev device info queries, and use only lvm native device info. . For external_device_info_source="udev", first check lvm native device info, then check libudev info. . Remove sleep/retry loop when attempting libudev queries for device info. udev info will simply be skipped if it's not immediately available. . Only set up a libdev connection if it will be used by obtain_device_list_from_udev/external_device_info_source. . For native multipath component detection, use /etc/multipath/wwids. If a device has a wwid matching an entry in the wwids file, then it's considered a multipath component. This is necessary to natively detect multipath components when the mpath device is not set up.
2021-06-09 01:12:09 +03:00
if (!dev_mpath_init(find_config_tree_str_allow_empty(cmd, devices_multipath_wwids_file_CFG, NULL))) {
ret = ECMD_FAILED;
goto_out;
}
if (!_cmd_no_meta_proc(cmd) && !_init_lvmlockd(cmd)) {
2015-03-05 23:00:44 +03:00
ret = ECMD_FAILED;
goto_out;
}
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
if (cmd->command->functions)
/* A command-line-specific function is used */
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
ret = cmd->command->functions->fn(cmd, argc, argv);
else
/* The old style command-name function is used */
ret = cmd->command->fn(cmd, argc, argv);
2004-03-26 15:00:24 +03:00
2015-03-05 23:00:44 +03:00
lvmlockd_disconnect();
fin_locking(cmd);
2004-03-26 15:00:24 +03:00
if (!_cmd_no_meta_proc(cmd) && find_config_tree_bool(cmd, global_notify_dbus_CFG, NULL))
lvmnotify_send(cmd);
2004-03-26 15:00:24 +03:00
out:
devices: rework libudev usage related to config settings: obtain_device_info_from_udev (controls if lvm gets a list of devices from readdir /dev or from libudev) external_device_info_source (controls if lvm asks libudev for device information) . Make the obtain_device_list_from_udev setting affect only the choice of readdir /dev vs libudev. The setting no longer controls if udev is used for device type checks. . Change obtain_device_list_from_udev default to 0. This helps avoid boot timeouts due to slow libudev queries, avoids reported failures from udev_enumerate_scan_devices, and avoids delays from "device not initialized in udev database" errors. Even without errors, for a system booting with 1024 PVs, lvm2-pvscan times improve from about 100 sec to 15 sec, and the pvscan command from about 64 sec to about 4 sec. . For external_device_info_source="none", remove all libudev device info queries, and use only lvm native device info. . For external_device_info_source="udev", first check lvm native device info, then check libudev info. . Remove sleep/retry loop when attempting libudev queries for device info. udev info will simply be skipped if it's not immediately available. . Only set up a libdev connection if it will be used by obtain_device_list_from_udev/external_device_info_source. . For native multipath component detection, use /etc/multipath/wwids. If a device has a wwid matching an entry in the wwids file, then it's considered a multipath component. This is necessary to natively detect multipath components when the mpath device is not set up.
2021-06-09 01:12:09 +03:00
dev_mpath_exit();
hints_exit(cmd);
lvmcache_destroy(cmd, 1, 1);
label_scan_destroy(cmd);
devices_file_exit(cmd);
2004-03-26 15:00:24 +03:00
if ((config_string_cft = remove_config_tree_by_source(cmd, CONFIG_STRING)))
dm_config_destroy(config_string_cft);
config: differentiate command and metadata profiles and consolidate profile handling code - When defining configuration source, the code now uses separate CONFIG_PROFILE_COMMAND and CONFIG_PROFILE_METADATA markers (before, it was just CONFIG_PROFILE that did not make the difference between the two). This helps when checking the configuration if it contains correct set of options which are all in either command-profilable or metadata-profilable group without mixing these groups together - so it's a firm distinction. The "command profile" can't contain "metadata profile" and vice versa! This is strictly checked and if the settings are mixed, such profile is rejected and it's not used. So in the end, the CONFIG_PROFILE_COMMAND set of options and CONFIG_PROFILE_METADATA are mutually exclusive sets. - Marking configuration with one or the other marker will also determine the way these configuration sources are positioned in the configuration cascade which is now: CONFIG_STRING -> CONFIG_PROFILE_COMMAND -> CONFIG_PROFILE_METADATA -> CONFIG_FILE/CONFIG_MERGED_FILES - Marking configuration with one or the other marker will also make it possible to issue a command context refresh (will be probably a part of a future patch) if needed for settings in global profile set. For settings in metadata profile set this is impossible since we can't refresh cmd context in the middle of reading VG/LV metadata and for each VG/LV separately because each VG/LV can have a different metadata profile assinged and it's not possible to change these settings at this level. - When command profile is incorrect, it's rejected *and also* the command exits immediately - the profile *must* be correct for the command that was run with a profile to be executed. Before this patch, when the profile was found incorrect, there was just the warning message and the command continued without profile applied. But it's more correct to exit immediately in this case. - When metadata profile is incorrect, we reject it during command runtime (as we know the profile name from metadata and not early from command line as it is in case of command profiles) and we *do continue* with the command as we're in the middle of operation. Also, the metadata profile is applied directly and on the fly on find_config_tree_* fn call and even if the metadata profile is found incorrect, we still need to return the non-profiled value as found in the other configuration provided or default value. To exit immediately even in this case, we'd need to refactor existing find_config_tree_* fns so they can return error. Currently, these fns return only config values (which end up with default values in the end if the config is not found). - To check the profile validity before use to be sure it's correct, one can use : lvm dumpconfig --commandprofile/--metadataprofile ProfileName --validate (the --commandprofile/--metadataprofile for dumpconfig will come as part of the subsequent patch) - This patch also adds a reference to --commandprofile and --metadataprofile in the cmd help string (which was missing before for the --profile for some commands). We do not mention --profile now as people should use --commandprofile or --metadataprofile directly. However, the --profile is still supported for backward compatibility and it's translated as: --profile == --metadataprofile for lvcreate, vgcreate, lvchange and vgchange (as these commands are able to attach profile to metadata) --profile == --commandprofile for all the other commands (--metadataprofile is not allowed there as it makes no sense) - This patch also contains some cleanups to make the code handling the profiles more readable...
2014-05-20 16:13:10 +04:00
config_profile_command_cft = remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);
config_profile_metadata_cft = remove_config_tree_by_source(cmd, CONFIG_PROFILE_METADATA);
cmd->profile_params->global_metadata_profile = NULL;
if (config_string_cft) {
/* Move this? */
if (!refresh_toolcontext(cmd))
stack;
} else if (config_profile_command_cft || config_profile_metadata_cft) {
if (!process_profilable_config(cmd))
stack;
}
2008-01-30 17:00:02 +03:00
if (ret == EINVALID_CMD_LINE && !cmd->is_interactive)
_short_usage(cmd->command->name);
2004-03-26 15:00:24 +03:00
log_debug("Completed: %s", cmd->cmd_line);
/*
* Reset all settings back to the persistent defaults that
* ignore everything supplied on the command line of the
* completed command.
*/
//_reset_current_settings_to_default(cmd);
//_apply_current_settings(cmd);
/*
* free off any memory the command used.
*/
dm_list_init(&cmd->arg_value_groups);
dm_pool_empty(cmd->mem);
reset_lvm_errno(1);
reset_log_duplicated();
2004-03-26 15:00:24 +03:00
return ret;
}
int lvm_return_code(int ret)
{
unlink_log_file(ret);
return (ret == ECMD_PROCESSED ? 0 : ret);
}
int lvm_split(char *str, int *argc, char **argv, int max)
2004-03-26 15:00:24 +03:00
{
char *b = str, *e;
char quote = 0;
2014-11-08 17:33:17 +03:00
*argc = 0;
2004-03-26 15:00:24 +03:00
while (*b) {
while (*b && isspace(*b))
b++;
if ((!*b) || (*b == '#'))
break;
if (*b == '\'' || *b == '"') {
quote = *b;
b++;
}
2004-03-26 15:00:24 +03:00
e = b;
while (*e && (quote ? *e != quote : !isspace(*e)))
2004-03-26 15:00:24 +03:00
e++;
argv[(*argc)++] = b;
if (!*e)
break;
*e++ = '\0';
quote = 0;
2004-03-26 15:00:24 +03:00
b = e;
if (*argc == max)
break;
}
if (*argc < max)
argv[*argc] = NULL;
2004-03-26 15:00:24 +03:00
return *argc;
}
/* Make sure we have always valid filedescriptors 0,1,2 */
static int _check_standard_fds(void)
{
int err = is_valid_fd(STDERR_FILENO);
if (!is_valid_fd(STDIN_FILENO) &&
!(stdin = fopen(_PATH_DEVNULL, "r"))) {
if (err)
perror("stdin stream open");
else
printf("stdin stream open: %s\n",
strerror(errno));
return 0;
}
if (!is_valid_fd(STDOUT_FILENO) &&
!(stdout = fopen(_PATH_DEVNULL, "w"))) {
if (err)
perror("stdout stream open");
/* else no stdout */
return 0;
}
if (!is_valid_fd(STDERR_FILENO) &&
!(stderr = fopen(_PATH_DEVNULL, "w"))) {
printf("stderr stream open: %s\n",
strerror(errno));
return 0;
}
return 1;
}
2016-07-08 17:47:51 +03:00
#define LVM_OUT_FD_ENV_VAR_NAME "LVM_OUT_FD"
#define LVM_ERR_FD_ENV_VAR_NAME "LVM_ERR_FD"
#define LVM_REPORT_FD_ENV_VAR_NAME "LVM_REPORT_FD"
static int _do_get_custom_fd(const char *env_var_name, int *fd)
{
const char *str;
char *endptr;
long int tmp_fd;
2016-07-08 17:47:51 +03:00
*fd = -1;
if (!(str = getenv(env_var_name)))
return 1;
errno = 0;
tmp_fd = strtol(str, &endptr, 10);
if (errno || *endptr || (tmp_fd < 0) || (tmp_fd > INT_MAX)) {
log_error("%s: invalid file descriptor.", env_var_name);
return 0;
}
*fd = tmp_fd;
return 1;
}
static int _get_custom_fds(struct custom_fds *custom_fds)
{
return _do_get_custom_fd(LVM_OUT_FD_ENV_VAR_NAME, &custom_fds->out) &&
_do_get_custom_fd(LVM_ERR_FD_ENV_VAR_NAME, &custom_fds->err) &&
_do_get_custom_fd(LVM_REPORT_FD_ENV_VAR_NAME, &custom_fds->report);
}
struct cmd_context *init_lvm(unsigned set_connections,
unsigned set_filters,
unsigned threaded)
2004-03-26 15:00:24 +03:00
{
struct cmd_context *cmd;
/*
* It's not necessary to use name mangling for LVM:
* - the character set used for LV names is subset of udev character set
* - when we check other devices (e.g. device_is_usable fn), we use major:minor, not dm names
*/
dm_set_name_mangling_mode(DM_STRING_MANGLING_NONE);
devices: rework libudev usage related to config settings: obtain_device_info_from_udev (controls if lvm gets a list of devices from readdir /dev or from libudev) external_device_info_source (controls if lvm asks libudev for device information) . Make the obtain_device_list_from_udev setting affect only the choice of readdir /dev vs libudev. The setting no longer controls if udev is used for device type checks. . Change obtain_device_list_from_udev default to 0. This helps avoid boot timeouts due to slow libudev queries, avoids reported failures from udev_enumerate_scan_devices, and avoids delays from "device not initialized in udev database" errors. Even without errors, for a system booting with 1024 PVs, lvm2-pvscan times improve from about 100 sec to 15 sec, and the pvscan command from about 64 sec to about 4 sec. . For external_device_info_source="none", remove all libudev device info queries, and use only lvm native device info. . For external_device_info_source="udev", first check lvm native device info, then check libudev info. . Remove sleep/retry loop when attempting libudev queries for device info. udev info will simply be skipped if it's not immediately available. . Only set up a libdev connection if it will be used by obtain_device_list_from_udev/external_device_info_source. . For native multipath component detection, use /etc/multipath/wwids. If a device has a wwid matching an entry in the wwids file, then it's considered a multipath component. This is necessary to natively detect multipath components when the mpath device is not set up.
2021-06-09 01:12:09 +03:00
if (!(cmd = create_toolcontext(0, NULL, 1, threaded, set_connections, set_filters))) {
2008-01-30 16:19:47 +03:00
return_NULL;
}
2004-03-26 15:00:24 +03:00
_cmdline.opt_names = get_opt_name(0);
if (stored_errno()) {
destroy_toolcontext(cmd);
return_NULL;
}
2004-03-26 15:00:24 +03:00
return cmd;
}
void lvm_fin(struct cmd_context *cmd)
2004-03-26 15:00:24 +03:00
{
partial revert "command: Skip some memory zeroing." This partially reverts commit da37cbd24fc0073f3f00a3b7aac7807d2185b829. As the _cmdline structure use mempool for allocated ellement that is being release on cmd_context close. Before the better fix is made - restore previous logic and reinitialize cmd structures again for new cmd_context. Problem can be hit with e.g. this test run: make check_local T=foreign LVM_VALGRIND_DMEVENTD=1 Invalid read of size 1 at 0x4C31C83: strcmp (vg_replace_strmem.c:846) by 0x6BA0939: _find_command (lvmcmdline.c:1555) by 0x6BA4304: lvm_run_command (lvmcmdline.c:2810) by 0x6BD5E02: lvm2_run (lvmcmdlib.c:91) by 0x685607E: dmeventd_lvm2_run (dmeventd_lvm.c:118) by 0x6652684: _use_policy (dmeventd_thin.c:117) by 0x6652E56: process_event (dmeventd_thin.c:298) by 0x10CC5A: _do_process_event (dmeventd.c:945) by 0x10CF83: _monitor_thread (dmeventd.c:1033) by 0x54B35E0: start_thread (in /usr/lib64/libpthread-2.26.9000.so) by 0x57C30EE: clone (in /usr/lib64/libc-2.26.9000.so) Address 0x6266270 is 4,352 bytes inside a block of size 8,192 free'd at 0x4C2ED68: free (vg_replace_malloc.c:530) by 0x5289142: dm_free_wrapper (dbg_malloc.c:393) by 0x528998A: _free_chunk (pool-fast.c:318) by 0x52892A6: dm_pool_destroy (pool-fast.c:78) by 0x6A8E52C: destroy_toolcontext (toolcontext.c:2254) by 0x6BA5BD6: lvm_fin (lvmcmdline.c:3327) by 0x6BD5EA7: lvm2_exit (lvmcmdlib.c:123) by 0x6856013: dmeventd_lvm2_exit (dmeventd_lvm.c:103) by 0x66535B8: unregister_device (dmeventd_thin.c:432) by 0x10CBBC: _do_unregister_device (dmeventd.c:926) by 0x10CD74: _monitor_unregister (dmeventd.c:979) by 0x10D094: _monitor_thread (dmeventd.c:1066) by 0x54B35E0: start_thread (in /usr/lib64/libpthread-2.26.9000.so) by 0x57C30EE: clone (in /usr/lib64/libc-2.26.9000.so) Block was alloc'd at at 0x4C2DBBB: malloc (vg_replace_malloc.c:299) by 0x5288F46: dm_malloc_aux (dbg_malloc.c:287) by 0x52890AC: dm_malloc_wrapper (dbg_malloc.c:371) by 0x52898E6: _new_chunk (pool-fast.c:286) by 0x52893BA: dm_pool_alloc_aligned (pool-fast.c:106) by 0x5289310: dm_pool_alloc (pool-fast.c:90) by 0x6A8A21A: _load_config_file (toolcontext.c:808) by 0x6A8A3D9: _init_lvm_conf (toolcontext.c:842) by 0x6A8D3BD: create_toolcontext (toolcontext.c:1941) by 0x6BA5B24: init_lvm (lvmcmdline.c:3308) by 0x6BD5B7C: cmdlib_lvm2_init (lvmcmdlib.c:34) by 0x6BD5EB8: lvm2_init (lvm2cmd.c:20) by 0x6855EA7: dmeventd_lvm2_init (dmeventd_lvm.c:67) by 0x665305F: register_device (dmeventd_thin.c:352) by 0x10CB7A: _do_register_device (dmeventd.c:916) by 0x10CEE4: _monitor_thread (dmeventd.c:1006) by 0x54B35E0: start_thread (in /usr/lib64/libpthread-2.26.9000.so) by 0x57C30EE: clone (in /usr/lib64/libc-2.26.9000.so)
2018-02-09 12:51:02 +03:00
_unregister_commands();
2004-03-26 15:00:24 +03:00
destroy_toolcontext(cmd);
udev_fin_library_context();
2004-03-26 15:00:24 +03:00
}
static int _run_script(struct cmd_context *cmd, int argc, char **argv)
{
FILE *script;
char buffer[CMD_LEN];
int ret = ENO_SUCH_CMD;
2004-03-26 15:00:24 +03:00
int magic_number = 0;
char *script_file = argv[0];
int largc;
char *largv[MAX_ARGS];
2004-03-26 15:00:24 +03:00
if ((script = fopen(script_file, "r")) == NULL)
2004-03-26 15:00:24 +03:00
return ENO_SUCH_CMD;
while (fgets(buffer, sizeof(buffer), script) != NULL) {
if (!magic_number) {
if (buffer[0] == '#' && buffer[1] == '!')
magic_number = 1;
else {
ret = ENO_SUCH_CMD;
break;
}
2004-03-26 15:00:24 +03:00
}
if ((strlen(buffer) == sizeof(buffer) - 1)
&& (buffer[sizeof(buffer) - 1] - 2 != '\n')) {
buffer[50] = '\0';
log_error("Line too long (max 255) beginning: %s",
buffer);
ret = EINVALID_CMD_LINE;
break;
}
if (lvm_split(buffer, &largc, largv, MAX_ARGS) == MAX_ARGS) {
2004-03-26 15:00:24 +03:00
buffer[50] = '\0';
log_error("Too many arguments: %s", buffer);
ret = EINVALID_CMD_LINE;
break;
}
if (!largc)
2004-03-26 15:00:24 +03:00
continue;
if (!strcmp(largv[0], "quit") || !strcmp(largv[0], "exit"))
2004-03-26 15:00:24 +03:00
break;
ret = lvm_run_command(cmd, largc, largv);
/*
* FIXME: handling scripts with invalid or failing commands
* could use some cleaning up, e.g. error_message_produced
* check and error are repeated again in the caller.
*/
if (ret == ENO_SUCH_CMD)
break;
2008-06-06 23:28:35 +04:00
if (ret != ECMD_PROCESSED) {
if (!error_message_produced()) {
log_debug(INTERNAL_ERROR "Failed command did not use log_error");
2008-06-06 23:28:35 +04:00
log_error("Command failed with status code %d.", ret);
}
break;
}
2004-03-26 15:00:24 +03:00
}
if (fclose(script))
log_sys_error("fclose", script_file);
2004-03-26 15:00:24 +03:00
return ret;
}
static void _nonroot_warning(void)
{
if (getuid() || geteuid())
log_warn("WARNING: Running as a non-root user. Functionality may be unavailable.");
}
int lvm2_main(int argc, char **argv)
2004-03-26 15:00:24 +03:00
{
2008-11-18 13:13:23 +03:00
const char *base;
2004-03-26 15:00:24 +03:00
int ret, alias = 0;
2016-07-08 17:47:51 +03:00
struct custom_fds custom_fds;
2004-03-26 15:00:24 +03:00
struct cmd_context *cmd;
int run_shell = 0;
int run_script = 0;
const char *run_name;
const char *run_command_name = NULL;
2004-03-26 15:00:24 +03:00
if (!argv)
return EINIT_FAILED;
base = last_path_component(argv[0]);
if (strcmp(base, "lvm") && strcmp(base, "lvm.static") &&
strcmp(base, "initrd-lvm"))
2004-03-26 15:00:24 +03:00
alias = 1;
if (!_check_standard_fds())
return EINIT_FAILED;
2016-07-08 17:47:51 +03:00
if (!_get_custom_fds(&custom_fds))
return EINIT_FAILED;
2016-07-08 17:47:51 +03:00
if (!daemon_close_stray_fds(base, getenv("LVM_SUPPRESS_FD_WARNINGS") ? 1 : 0,
STDERR_FILENO, &custom_fds))
return EINIT_FAILED;
2016-07-08 17:47:51 +03:00
if (!init_custom_log_streams(&custom_fds))
return EINIT_FAILED;
if (is_static() && strcmp(base, "lvm.static") &&
path_exists(LVM_PATH) &&
!getenv("LVM_DID_EXEC")) {
2012-03-02 01:17:29 +04:00
if (setenv("LVM_DID_EXEC", base, 1))
log_sys_error("setenv", "LVM_DID_EXEC");
if (execvp(LVM_PATH, argv) == -1)
log_sys_error("execvp", LVM_PATH);
2012-03-02 01:17:29 +04:00
if (unsetenv("LVM_DID_EXEC"))
log_sys_error("unsetenv", "LVM_DID_EXEC");
}
if (!alias && argc > 1) {
/* "version" command is simple enough so it doesn't need any complex init */
if (!strcmp(argv[1], "version"))
return lvm_return_code(version(NULL, argc, argv));
/* turn 'lvm -h', 'lvm --help', 'lvm -?' into 'lvm help' */
if (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-?"))
argv[1] = (char *)"help";
if (*argv[1] == '-') {
log_error("Specify options after a command: lvm [command] [options].");
return EINVALID_CMD_LINE;
}
}
/* turn command -? into command -h and lvm command -? into lvm command -h */
if (alias && (argc > 1) && !strcmp(argv[1], "-?"))
argv[1] = (char *)"-h";
if (!alias && (argc > 2) && !strcmp(argv[2], "-?"))
argv[2] = (char *)"-h";
if (!(cmd = init_lvm(0, 0, 0)))
return EINIT_FAILED;
/* Store original argv location so we may customise it if we become a daemon */
cmd->argv = argv;
commands: new method for defining commands . Define a prototype for every lvm command. . Match every user command with one definition. . Generate help text and man pages from them. The new file command-lines.in defines a prototype for every unique lvm command. A unique lvm command is a unique combination of: command name + required option args + required positional args. Each of these prototypes also includes the optional option args and optional positional args that the command will accept, a description, and a unique string ID for the definition. Any valid command will match one of the prototypes. Here's an example of the lvresize command definitions from command-lines.in, there are three unique lvresize commands: lvresize --size SizeMB LV OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB, --poolmetadatasize SizeMB OP: PV ... ID: lvresize_by_size DESC: Resize an LV by a specified size. lvresize LV PV ... OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --resizefs, --stripes Number, --stripesize SizeKB ID: lvresize_by_pv DESC: Resize an LV by specified PV extents. FLAGS: SECONDARY_SYNTAX lvresize --poolmetadatasize SizeMB LV_thinpool OO: --alloc Alloc, --autobackup Bool, --force, --nofsck, --nosync, --noudevsync, --reportformat String, --stripes Number, --stripesize SizeKB OP: PV ... ID: lvresize_pool_metadata_by_size DESC: Resize a pool metadata SubLV by a specified size. The three commands have separate definitions because they have different required parameters. Required parameters are specified on the first line of the definition. Optional options are listed after OO, and optional positional args are listed after OP. This data is used to generate corresponding command definition structures for lvm in command-lines.h. usage/help output is also auto generated, so it is always in sync with the definitions. Every user-entered command is compared against the set of command structures, and matched with one. An error is reported if an entered command does not have the required parameters for any definition. The closest match is printed as a suggestion, and running lvresize --help will display the usage for each possible lvresize command. The prototype syntax used for help/man output includes required --option and positional args on the first line, and optional --option and positional args enclosed in [ ] on subsequent lines. command_name <required_opt_args> <required_pos_args> [ <optional_opt_args> ] [ <optional_pos_args> ] Command definitions that are not to be advertised/suggested have the flag SECONDARY_SYNTAX. These commands will not be printed in the normal help output. Man page prototypes are also generated from the same original command definitions, and are always in sync with the code and help text. Very early in command execution, a matching command definition is found. lvm then knows the operation being done, and that the provided args conform to the definition. This will allow lots of ad hoc checking/validation to be removed throughout the code. Each command definition can also be routed to a specific function to implement it. The function is associated with an enum value for the command definition (generated from the ID string.) These per-command-definition implementation functions have not yet been created, so all commands currently fall back to the existing per-command-name implementation functions. Using per-command-definition functions will allow lots of code to be removed which tries to figure out what the command is meant to do. This is currently based on ad hoc and complicated option analysis. When using the new functions, what the command is doing is already known from the associated command definition.
2016-08-12 23:52:18 +03:00
/*
* If the invocation command name wasn't itself an alias, shift to the
* first arg. After this point, run_name holds one of:
* the LVM command name we want to run;
* the LVM script name (handled through ENO_SUCH_CMD below);
* NULL for a shell (if readline is enabled).
*/
if (!alias) {
argc--;
argv++;
run_name = argv[0];
} else
run_name = dm_basename(argv[0]);
2004-03-26 15:00:24 +03:00
/*
* Decide if we are running a shell or a command or a script. When
* there is no run_name, it's a shell, when run_name is a recognized
* lvm command it's that command, when run_name is not a recognized
* command name, try it as an lvm script.
*/
if (!run_name)
run_shell = 1;
else if (!find_command_name(run_name))
run_script = 1;
else
run_command_name = run_name;
/*
* NULL run_command_name means register all command defs because
* a script or shell needs to access any command name, while a
* single command needs to access only defs for the named command.
*/
if (!lvm_register_commands(cmd, run_command_name)) {
ret = ECMD_FAILED;
goto out;
}
if (run_shell) {
#if defined(READLINE_SUPPORT) || defined(EDITLINE_SUPPORT)
_nonroot_warning();
if (!_prepare_profiles(cmd)) {
ret = ECMD_FAILED;
goto out;
}
ret = lvm_shell(cmd, &_cmdline);
2004-03-26 15:00:24 +03:00
goto out;
#else
log_fatal("Please supply an LVM command.");
_display_help();
ret = EINVALID_CMD_LINE;
goto out;
2004-03-26 15:00:24 +03:00
#endif
}
_nonroot_warning();
if (run_script)
2004-03-26 15:00:24 +03:00
ret = _run_script(cmd, argc, argv);
else
ret = lvm_run_command(cmd, argc, argv);
if (ret == ENO_SUCH_CMD) {
2017-07-10 18:43:47 +03:00
log_error("No such command. Try 'lvm help'.");
goto out;
}
2004-03-26 15:00:24 +03:00
2008-06-06 23:28:35 +04:00
if ((ret != ECMD_PROCESSED) && !error_message_produced()) {
log_debug(INTERNAL_ERROR "Failed command did not use log_error");
2008-06-06 23:28:35 +04:00
log_error("Command failed with status code %d.", ret);
}
2004-03-26 15:00:24 +03:00
out:
lvm_fin(cmd);
2017-02-18 21:09:24 +03:00
return lvm_return_code(ret);
2004-03-26 15:00:24 +03:00
}