# $Id$ # # Copyright (c) 2001-2017 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary VolumeEfficiency ComponentState Module ## @author dl-nacl-dev@netapp.com, benjaram@netapp.com ## @status public ## @pod here =head1 NAME NACL::CS::VolumeEfficiency =head1 DESCRIPTION C is a derived class of L. It represents the state of an ONTAP VolumeEfficiency. A related class is L, which represents access to an ONTAP VolumeEfficiency. =head1 ATTRIBUTES The individual pieces of data that are part of the state of the VolumeEfficiency element are the attributes of the VolumeEfficiency ComponentState. =over =item C<< "verbose" >> =item C<< "op_status" >> =item C<< "state" >> =item C<< "last_op_size" >> =item C<< "checkpoint_progress" >> =item C<< "last_op_size_text" >> =item C<< "policy" >> =item C<< "gathering_begin_time" >> =item C<< "dedupe_begin_time" >> =item C<< "op_status_text" >> =item C<< "refid" >> =item C<< "checkpoint_sub_stage" >> =item C<< "inline" >> =item C<< "fingerprints_sorted" >> =item C<< "checkpoint_op_type_text" >> =item C<< "fingerprints_deleted" >> =item C<< "logical_data_limit" >> =item C<< "background_compression" >> =item C<< "schedule" >> =item C<< "verify_trigger_rate" >> =item C<< "checking_begin_time" >> =item C<< "last_op_end_int" >> =item C<< "total_verify_time" >> =item C<< "policy_id" >> =item C<< "type" >> =item C<< "last_op_error" >> =item C<< "checkpoint_stage" >> =item C<< "stage" >> Applicable for CMode CLI. Note that this option is returned by CMode ZAPI, so if this is provided through either filter/requested_fields for CMode, then the call will always be made through the CMode-CLI implementation. =item C<< "blks_skipped_sharing" >> =item C<< "type_text" >> =item C<< "checkpoint_time_int" >> =item C<< "checkpoint_stage_text" >> =item C<< "stale_fingerprint_percentage" >> =item C<< "checkpoint_op_type" >> =item C<< "duplicate_blocks_found" >> =item C<< "verify_suspend_count" >> =item C<< "changelog_usage" >> =item C<< "min_blocks_shared" >> =item C<< "queued_job" >> =item C<< "last_op_begin_int" >> =item C<< "checkpoint_sub_stage_text" >> =item C<< "state_text" >> =item C<< "logical_data_percent" >> =item C<< "volume" >> =item C<< "fingerprints_gathered" >> =item C<< "row_status" >> =item C<< "progress" >> =item C<< "vserver" >> =item C<< "path" >> =item C<< "blocks_deduplicated" >> =item C<< "last_op_end" >> =item C<< "logical_data_size" >> =item C<< "checkpoint_time" >> =item C<< "inline_compression" >> =item C<< "sorting_begin_time" >> =item C<< "last_op_begin" >> =item C<< "last_op_state" >> =item C<< "last_success_op_begin >> =item C<< "last_success_op_end >> =item C<< inline_compression_text >> Filled in for CMode CLI. =item C<< last_success_op_begin_int >> Filled in for CMode CLI. =item C<< compression >> Filled in for CMode CLI. =item C<< compression_text >> Filled in for CMode CLI. =item C<< last_success_op_end_int >> Filled in for CMode CLI. =item C<< inline_compressiontemp >> Filled in for CMode CLI. =item C<< background_compressiontemp >> Filled in for CMode CLI. =item C<< is_constituent >> Filled in for CMode CLI. =item C<< idd >> Filled in for CMode CLI. =item C<< idd_text >> Filled in for CMode CLI. =item C<< auto_state >> Filled in for CMode CLI. =item C<< changelog_overflow >> Filled in for CMode CLI. =item C<< quick_check_fsize >> Filled in for CMode CLI. =item C<< savings_potential >> Filled in for CMode CLI. =item C<< op_frequency >> Filled in for CMode CLI. =item C<< changelog_size >> Changelog Size, possible value(s) are [KB,MB,GB,TB,PB] Filled in for CMode CLI. =item C<< optimize >> *Optimization, possible value(s) are performance,space-saving Filled in for CMode CLI. =item C<< gathering_phase2_begin_time >> *Gathering Phase 2 Begin Filled in for CMode CLI. =item C<< compression_changelog_size >> Compression Changelog Size, possible value(s) are [KB,MB,GB,TB,PB] Filled in for CMode CLI. =item C<< vault_transfer_log_size >> Vault transfer log Size, possible value(s) are [KB,MB,GB,TB,PB] Filled in for CMode CLI. =item C<< same_fp_blocks >> Same FP Count Filled in for CMode CLI. =item C<< num_stale_aux_recipients >> Stale Auxiliary Recipient Count Filled in for CMode CLI. =item C<< num_skipshare_blocks_upper >> Skip Share Blocks Upper Filled in for CMode CLI. =item C<< mismatch_data_blks >> Mismatched Data Filled in for CMode CLI. =item C<< num_max_ref_hits >> Max RefCount Hits Filled in for CMode CLI. =item C<< num_stale_aux_recipient_blocks >> Stale Auxiliary Recipient Block Count Filled in for CMode CLI. =item C<< num_skipped_aux_sharing >> Unattempted Auxiliary Recipient Share Filled in for CMode CLI. =item C<< same_vbn_blocks >> Same VBN Filled in for CMode CLI. =item C<< num_stale_aux_mismatch >> Mismatched Recipient Block Pointers Filled in for CMode CLI. =item C<< num_sorted_blocks >> Total Sorted Blocks Filled in for CMode CLI. =item C<< num_out_of_space_errors >> Num Out Of Space Filled in for CMode CLI. =item C<< same_data_blocks >> Same Data Filled in for CMode CLI. =item C<< num_stale_donors >> Stale Donor Count Filled in for CMode CLI. =item C<< num_stale_recipients >> Stale Recipient Count Filled in for CMode CLI. =item C<< fp_mismatch_overwrites >> Mismatch Due To Overwrites Filled in for CMode CLI. =item C<< same_sharing_records >> Same Sharing Records Filled in for CMode CLI. =item C<< num_skipshare_blocks_delta >> Skip Share Blocks Delta Filled in for CMode CLI. =item C<< same_fbn_blocks >> Same FBN Filled in for CMode CLI. =item C<< blks_processed_for_compression >> Blocks Processed For Compression Filled in for CMode CLI. =item C<< estimated_savings_potential >> Estimated Savings Potential Filled in for CMode CLI. =item C<< est_num_lpf_duplicates_found >> LPF Duplicate Fingerprints Filled in for CMode CLI. =item C<< est_num_duplicates_found >> Duplicate Fingerprints Filled in for CMode CLI. =item C<< est_num_clamp_duplicates_found >> Clamp Duplicate Fingerprints Filled in for CMode CLI. =item C<< est_num_fingerprints_sampled >> Fingerprints Sampled Filled in for CMode CLI. =item C<< last_op_begin_text >> Last Op Begin Text Filled in for CMode CLI. =item C<< last_success_op_end_text >> Last Succeess Op End Text Filled in for CMode CLI. =item C<< num_vbn_absent >> VBN Absent Count Filled in for CMode CLI. =item C<< last_op_end_text >> Last Op End Text Filled in for CMode CLI. =item C<< last_success_op_begin_text >> Last Succeess Op Begin Text Filled in for CMode CLI. =item C<< no_op_blocks >> No Op Filled in for CMode CLI. =item C<< compression_type >> compression type shows the type of compression. The values can be: secondary [default], adaptive Filled in for CMode CLI. =item C<< data_compaction >> data compaction displays information only for those volumes that match the specified data compaction setting. The values can be: true/false Filled in for CMode CLI/ZAPI. Maps to: CM ZAPI : is-data-compaction-enabled =item C<< application_io_size >> application-io-size displays the application IO size configured for adaptive compression. The values can be: {default|8K|16K|32K} =back =cut package NACL::CS::VolumeEfficiency; use strict; use warnings; use Params::Validate qw(validate); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use NACL::ComponentUtils qw(Dumper); use base 'NACL::CS::ComponentState::ONTAP'; use NATE::Exceptions::Argument qw(:try); use NACL::Exceptions::InvalidChoice; use Class::MethodMaker [ scalar => 'verbose', scalar => 'op_status', scalar => 'state', scalar => 'last_op_size', scalar => 'checkpoint_progress', scalar => 'last_op_size_text', scalar => 'policy', scalar => 'gathering_begin_time', scalar => 'dedupe_begin_time', scalar => 'op_status_text', scalar => 'refid', scalar => 'checkpoint_sub_stage', scalar => 'inline', scalar => 'fingerprints_sorted', scalar => 'checkpoint_op_type_text', scalar => 'fingerprints_deleted', scalar => 'logical_data_limit', scalar => 'background_compression', scalar => 'schedule', scalar => 'verify_trigger_rate', scalar => 'checking_begin_time', scalar => 'last_op_end_int', scalar => 'total_verify_time', scalar => 'policy_id', scalar => 'type', scalar => 'last_op_error', scalar => 'checkpoint_stage', scalar => 'stage', scalar => 'blks_skipped_sharing', scalar => 'type_text', scalar => 'checkpoint_time_int', scalar => 'checkpoint_stage_text', scalar => 'stale_fingerprint_percentage', scalar => 'checkpoint_op_type', scalar => 'duplicate_blocks_found', scalar => 'verify_suspend_count', scalar => 'changelog_usage', scalar => 'min_blocks_shared', scalar => 'queued_job', scalar => 'last_op_begin_int', scalar => 'checkpoint_sub_stage_text', scalar => 'state_text', scalar => 'logical_data_percent', scalar => 'volume', scalar => 'fingerprints_gathered', scalar => 'row_status', scalar => 'progress', scalar => 'vserver', scalar => 'path', scalar => 'blocks_deduplicated', scalar => 'last_op_end', scalar => 'logical_data_size', scalar => 'checkpoint_time', scalar => 'inline_compression', scalar => 'sorting_begin_time', scalar => 'last_op_begin', scalar => 'last_op_state', scalar => 'last_success_op_begin', scalar => 'last_success_op_end', scalar => 'inline_compression_text', scalar => 'last_success_op_begin_int', scalar => 'compression', scalar => 'compression_text', scalar => 'last_success_op_end_int', scalar => 'inline_compressiontemp', scalar => 'background_compressiontemp', scalar => 'is_constituent', scalar => 'idd', scalar => 'idd_text', scalar => 'auto_state', scalar => 'changelog_overflow', scalar => 'quick_check_fsize', scalar => 'savings_potential', scalar => 'op_frequency', scalar => 'changelog_size', scalar => 'optimize', scalar => 'gathering_phase2_begin_time', scalar => 'compression_changelog_size', scalar => 'vault_transfer_log_size', scalar => 'same_fp_blocks', scalar => 'num_stale_aux_recipients', scalar => 'num_skipshare_blocks_upper', scalar => 'mismatch_data_blks', scalar => 'num_max_ref_hits', scalar => 'num_stale_aux_recipient_blocks', scalar => 'num_skipped_aux_sharing', scalar => 'same_vbn_blocks', scalar => 'num_stale_aux_mismatch', scalar => 'num_sorted_blocks', scalar => 'num_out_of_space_errors', scalar => 'same_data_blocks', scalar => 'num_stale_donors', scalar => 'num_stale_recipients', scalar => 'fp_mismatch_overwrites', scalar => 'same_sharing_records', scalar => 'num_skipshare_blocks_delta', scalar => 'same_fbn_blocks', scalar => 'blks_processed_for_compression', scalar => 'estimated_savings_potential', scalar => 'est_num_lpf_duplicates_found', scalar => 'est_num_duplicates_found', scalar => 'est_num_clamp_duplicates_found', scalar => 'est_num_fingerprints_sampled', scalar => 'last_op_begin_text', scalar => 'last_success_op_end_text', scalar => 'num_vbn_absent', scalar => 'last_op_end_text', scalar => 'last_success_op_begin_text', scalar => 'no_op_blocks', scalar => 'compression_type', scalar => 'data_compaction', scalar => 'application_io_size' ]; sub isa { $Log->enter() if $may_enter; my ($pkg_or_obj, $kind) = @_; my $isa = $pkg_or_obj->_build_isa( kind => $kind, alias => 'NACL::CS::Efficiency' ); $Log->exit() if $may_exit; return $isa; } ## end sub isa =head1 METHODS =head2 fetch my $VolumeEfficiency_state = NACL::CS::VolumeEfficiency->fetch(command_interface => $ci, ...); my @VolumeEfficiency_states = NACL::CS::VolumeEfficiency->fetch(command_interface => $ci, ...); (Class method) Discovers which elements are present and returns their state in ComponentState objects. Called in scalar context it returns only one state object, in list context it returns all state objects. See L for a more detailed description along with a complete explanation of the options it accepts. Uses a CMode CLI/ZAPI or a 7Mode CLI APISet. =over =item Exceptions =over =item C When there are no elements matching the query specified or elements of that type doesn't exist, then this exception will be thrown. =back =back =cut sub fetch { $Log->enter() if $may_enter; my $pkg = shift; my @state_objs = $pkg->SUPER::fetch( @_, show_cmd => 'volume efficiency show', choices => [ { method => '_fetch_cmode_cli', interface => 'CLI', set => 'CMode', }, { method => '_fetch_cmode_zapi', interface => 'ZAPI', set => 'CMode', check => '_check_cm_zapi', }, { method => '_fetch_7mode_cli', interface => 'CLI', set => '7Mode', }, { method => '_fetch_7mode_zapi', interface => 'ZAPI', set => '7Mode', }, ], exception_text => 'No matching volume efficiency(s) found' ); $Log->exit() if $may_exit; return wantarray ? @state_objs : $state_objs[0]; } ## end sub fetch sub _fetch_cmode_cli { $Log->enter() if $may_enter; my $pkg = shift; my @state_objs = $pkg->SUPER::_fetch_cmode_cli(@_, api => 'volume_efficiency_show'); $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_cli sub _fetch_cmode_zapi { $Log->enter() if $may_enter; my ($pkg, %opts) = @_; # Need to work around ONTAP bug 677448: vserver and path do not # show up in the returned results if desired-attributes is provided # and does not contain vserver and path. Hence, we'll add them if # requested_fields is provided and does not contain these my $requested_fields = $opts{requested_fields}; if (@$requested_fields) { my %req_field_hash = map { $_ => 1 } @$requested_fields; $req_field_hash{vserver} = 1; $req_field_hash{path} = 1; $opts{requested_fields} = [keys %req_field_hash]; } my $filter = $opts{filter}; my %deep_copy = %$filter; # If volume is specified as filter, we convert it into path # Note that we should NOT construct the filter if the volume contains # special characters. For example, if volume is passed as "!vol0", # then the path constructed would wrongly be "/vol/!vol0". Instead, # let's filter in Perl code by setting _apply_filter to 1. my $reset_apply_filter; if (defined $filter->{'volume'}) { my $volume = $filter->{volume}; if ($pkg->_check_relational_regex_filter(filter_value => $volume)) { $reset_apply_filter = 1; } else { $deep_copy{path} = "/vol/" . $filter->{'volume'}; } } $opts{filter} = \%deep_copy; my @state_objs = $pkg->SUPER::_fetch_cmode_zapi( %opts, api => 'sis_get_iter', copy => [ qw( state last-op-size checkpoint-progress policy stale-fingerprint-percentage checkpoint-sub-stage logical-data-limit schedule type last-op-error checkpoint-stage checkpoint-op-type path vserver progress logical-data-size checkpoint-time last-op-state quick-check-fsize is-constituent application-io-size ) ], map => { 'blks-skipped-sharing' => 'blocks-skipped-sharing', 'changelog-usage' => 'changelog-used-percent', 'min-blocks-shared' => 'minimum-blocks-shared', 'queued-job' => 'queued-job-type', 'last-op-end' => 'last-op-end-timestamp', 'last-op-begin' => 'last-op-begin-timestamp', 'last-success-op-begin' => 'last-success-op-begin-timestamp', 'last-success-op-end' => 'last-success-op-end-timestamp', 'compression' => 'is-compression-enabled', 'inline-compression' => 'is-inline-compression-enabled', 'idd' => 'is-idd-enabled', 'op-status' => 'status', 'data-compaction' => 'is-data-compaction-enabled', }, ); ${$opts{_apply_filter}} = 1 if ($reset_apply_filter); $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_zapi # ZAPI does not provide the value of "stage". Burt 712570. sub _check_cm_zapi { $Log->enter() if $may_enter; my ($pkg, %opts) = @_; my $want_stage = exists $opts{filter}{stage} || grep { $_ eq 'stage' } @{$opts{requested_fields}}; if ($want_stage) { $Log->exit() if $may_exit; NACL::Exceptions::InvalidChoice->throw('Cannot use the CMode ZAPI ' . "implementation because the field 'stage' was required, but " . 'ZAPI does not return this value'); } $Log->exit() if $may_exit; } sub _fetch_7mode_cli { $Log->enter() if $may_enter; my $pkg = shift; my %opts = validate @_, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my ($response, $caught_exception, $output, %row, %output, @state_objs, %api_args); my $filter = $opts{filter}; my $requested_fields = $opts{requested_fields}; # path takes precedence if (exists($filter->{path})) { $api_args{path} = $filter->{path} if (exists($filter->{path})); } else { $api_args{path} = "/vol/$filter->{volume}" if (exists($filter->{volume})); } # Check if any of the fields filled only with verbose option my @fields_only_in_verbose = qw (background_compression inline_compression progress type schedule changelog_usage queued_jobs stage checkpoint_op_type checkpoint-stage checkpoint_sub-stage checkpoint progress fingerprints_gathered fingerprints_sorted duplicate_blocks_found fingerprints_deleted verify_trigger_rate total_verify_time verify_suspend_count policy_id compression ); if ($pkg->_want_any_field_of( requested_fields => $requested_fields, filter => $filter, fields_filled_by_api => \@fields_only_in_verbose, ) ) { $Log->debug("The API 'sis_status' will be invoked with -l option"); $api_args{verbose} = 1; } ## end if ( $pkg->_want_any_field_of...) try { $response = $apiset->sis_status(%api_args); } catch NACL::APISet::Exceptions::InvalidParamValueException with { $caught_exception = 1; }; return if ($caught_exception); $output = $response->get_parsed_output(); foreach my $status (@$output) { my $final_attributes = $pkg->_hash_copy( source => $status, copy => [ qw(background_compression inline_compression progress type schedule changelog_usage queued_jobs stage checkpoint_op_type checkpoint_sub-stage checkpoint_stage checkpoint progress fingerprints_gathered fingerprints_sorted duplicate_blocks_found fingerprints_deleted verify_trigger_rate total_verify_time verify_suspend_count policy_id path state progress compression) ], map => { 'status' => 'op_status', 'minimum_blocks_shared' => 'min_blocks_shared', 'blocks_skipped_sharing' => 'blks_skipped_sharing', 'last_operation_state' => 'last_op_state', 'last_successful_operation_begin' => 'last_success_op_begin', 'last_successful_operation_end' => 'last_success_op_end', 'last_operation_begin' => 'last_op_begin', 'last_operation_end' => 'last_op_end', 'last_operation_size' => 'last_op_size', 'last_operation_error' => 'last_op_error', 'logical_data' => 'logical_data_percent', 'stale_fingerprints' => 'stale_fingerprint_percentage', 'checkpoint_time' => 'checkpoint_time_int', 'gathering_begin' => 'gathering_begin_time', 'sorting_begin' => 'sorting_begin_time', 'blocks_De-duplicated' => 'blocks_deduplicated', 'de-duping_begin' => 'dedupe_begin_time', 'checking_begin' => 'checking_begin_time', 'fp_sorted' => 'fingerprints_sorted', 'incompressible_data_detection' => 'idd', 'compression_quick_check_file_size' => 'quick_check_fsize', } ); foreach my $key (qw( compression idd inline_compression )) { if (defined($final_attributes->{$key})) { if ($final_attributes->{$key} =~ /disabled/i) { $final_attributes->{$key} = "false"; } elsif ($final_attributes->{$key} =~ /enabled/i) { $final_attributes->{$key} = "true"; } else { NATE::BaseException->throw( "Invalid value $final_attributes->{$key} for $key :" . "Should be either enable or disable only."); } ## end else [ if ( $final_attributes...)] } ## end if ( defined( $final_attributes...)) } ## end foreach my $key qw( compression idd inline_compression ) $final_attributes->{volume} = (split("/", $final_attributes->{path}))[2]; my $obj = $pkg->new(command_interface => $opts{command_interface}); $obj->_set_fields(row => $final_attributes); push(@state_objs, $obj); } ## end foreach my $status (@$output) $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_cli sub _fetch_7mode_zapi { $Log->enter() if $may_enter; my ($pkg, @args) = @_; my %opts = validate @args, $pkg->_fetch_backend_validate_spec(); my $apiset = $opts{apiset}; my $requested_fields = $opts{requested_fields}; my $filter = $opts{filter}; my (%sis_filter_args, $caught_exception, $response); # this is for obtaining records that match the filter # (path is the only filter) if (defined $filter->{'path'}) { $sis_filter_args{'path'} = $filter->{'path'}; } elsif (defined $filter->{'volume'}) { $sis_filter_args{'path'} = "/vol/" . $filter->{'volume'}; } else { NATE::Exceptions::Argument->throw('Either "path" or "volume" has to ' . 'be specified in the filter'); } my %req_field_filter = (requested_fields => $requested_fields, filter => $filter); # When sis_status is invoked in verbose mode, the information it # displays which is not displayed in non-verbose mode are all other # than 'state', 'path', 'status', 'progress'. # (e.g. idd, quick-check-fsize ) # Only if we require any of those fields # excluding the above four, we should invoke it in verbose mode. if ($pkg->_want_any_field_of( %req_field_filter, fields_filled_by_api => [ ( 'type', 'schedule', 'minimum-blocks-shared', 'blocks-skipped-sharing', 'last-operation-state', 'last-success-operation-begin-timestamp', 'last-success-operation-end-timestamp', 'last-operation-begin-timestamp', 'last-operation-end-timestamp', 'last-operation-size', 'last-operation-size-bytes', 'last-operation-error', 'changelog-used-percent', 'changelog-size', 'vault-transfer-log-size', 'compression-changelog-size', 'checkpoint-time', 'checkpoint-op-type', 'checkpoint-stage', 'checkpoint-sub-stage', 'checkpoint-progress', 'is-compression-enabled', 'is-inline-compression-enabled', 'idd', 'quick-check-fsize', 'queued-job-type', 'stale-fingerprint-percentage', ) ] ) ) { $sis_filter_args{verbose} = 'true'; } ## end if ( $pkg->_want_any_field_of...) # the zapi invocation is as follows # Execute sis_status with the filter parameters to get the # volume efficiency related paramters of a particular volume. my $info; my $num_exp = 14513; try { $info = $apiset->sis_status(%sis_filter_args)->get_parsed_output(); } catch NACL::APISet::Exceptions::ResponseException with { my $exception = shift; if ($exception->error_number() == $num_exp) { $caught_exception = 1; } else { # Some other sort of error $Log->exit() if $may_exit; $exception->throw(); } ## end else [ if ( $exception->error_number...)] }; if ($caught_exception) { $Log->exit() if $may_exit; return; } my @state_objs; foreach my $status (@{$info->[0]->{'sis-object'}[0]{'dense-status'}}) { my $final_attributes = $pkg->_hash_copy( source => $status, copy => [ qw( state path progress quick-check-fsize type schedule vault-transfer-log-size ), ], map => { 'status' => 'op_status', 'is-compression-enabled' => 'compression', 'is-inline-compression-enabled' => 'inline-compression', 'is-idd-enabled' => 'idd', 'minimum-blocks-shared' => 'min_blocks_shared', 'blocks-skipped-sharing' => 'blks_skipped_sharing', 'last-operation-state' => 'last_op_state', 'last-success-operation-begin-timestamp' => 'last_success_op_begin', 'last-success-operation-end-timestamp' => 'last_success_op_end', 'last-operation-begin-timestamp' => 'last_op_begin', 'last-operation-end-timestamp' => 'last_op_end', 'last-operation-size' => 'last_op_size', 'last-operation-error' => 'last_op_error', 'logical-data' => 'logical_data_percent', 'stale-fingerprint-percentage' => 'stale_fingerprint_percentage', 'checkpoint-time' => 'checkpoint_time_int', 'compression-changelog-size' => 'compression_changelog_size', 'changelog-size' => 'changelog_size', 'checkpoint-time' => 'checkpoint_time', 'checkpoint-op-type' => 'checkpoint_op_type', 'checkpoint-progress' => 'checkpoint_progress', 'checkpoint-sub-stage' => 'checkpoint_sub_stage', 'queued-job-type' => 'queued_job', 'changelog-used-percent' => 'changelog_usage', } ); my $obj = $pkg->new(command_interface => $opts{command_interface}); $obj->_set_fields(row => $final_attributes); push(@state_objs, $obj); } ## end foreach my $status ( @{ $info...}) $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_zapi # #This method normalizes the ZAPI values to the corresponding values of #CLI # sub _update_state_objs_cmode_zapi { $Log->enter() if $may_enter; my ($pkg, %args) = @_; $pkg->SUPER::_update_state_objs_cmode_zapi( %args, zapi_field_translations => { ucfirst => [qw(state op_status)], timestamp_to_string => [ qw(last-success-op-begin last-op-end last-op-begin last-success-op-end) ], }, ); foreach my $state_obj (@{$args{state_objs}}) { my $path = $state_obj->path(); if ( defined $path ) { $state_obj->volume((split("/", $state_obj->path()))[2]); } my $type = $state_obj->type(); if ( defined $type ) { if ( $type eq "regular" ) { $state_obj->type("Regular"); } elsif ( $type eq "snapvault" ) { $state_obj->type("SnapVault"); } } } $Log->exit() if $may_exit; } 1;