# # Copyright (c) 2001-2010 NetApp, Inc., All Rights Reserved # Any use, modification, or distribution is prohibited # without prior written consent from NetApp, Inc. # ## @summary ComponentState module for the method NACL::C::VolumeEfficiency->stat() ## @author dl-nacl-dev@netapp.com ## @status shared ## @pod here =head1 NAME NACL::CS::VolumeEfficiencyStat =head1 DESCRIPTION C is a derived class of L. Object(s) of this type are returned when NACL::C::VolumeEfficiency->stat() is invoked. (This module does not represent the state of any element, but is an object repesentation of the output obtained when the statistics of volume efficiency operations is queried) =head1 ATTRIBUTES The fields of the output are fields of the ComponentState object. =over =item C<< vserver >> Vserver Name =item C<< volume >> Volume Name =item C<< path >> Volume Path (in the form /vol/volume) =item C<< b >> =item C<< g >> =item C<< allocated_data >> Allocated Data =item C<< shared_data >> Shared Data =item C<< space_saved >> Space Saved =item C<< saved_percentage >> Saved Percentage =item C<< max_ref_count >> Maximum Refcount =item C<< total_processed_data >> Total Processed Data =item C<< total_process_time >> Total Processing Time =item C<< total_verify_time >> =item C<< num_sis_files >> Efficiency Files Count =item C<< num_succeeded_ops >> Succeeded Op Count =item C<< num_started_ops >> Started Op Count =item C<< num_failed_ops >> Failed Op Count =item C<< num_stopped_ops >> Stopped Op Count =item C<< num_deferred_ops >>> Deferred Op Count =item C<< num_check_ok_ops >> Check Ok Op Count =item C<< num_check_fail_ops >> Check Fail Op Count =item C<< num_check_susp_ops >> Check Suspended Op Count =item C<< num_fps_deleted >> Total Fingerprints Deleted =item C<< num_sorted_blocks >> Total Sorted Blocks =item C<< overlapped_blocks >> Overlapped Blocks =item C<< same_fp_blocks >> Same FP Count =item C<< same_fbn_blocks >> Same FBN =item C<< same_data_blocks >> Same Data Blocks =item C<< same_vbn_blocks >> Same VBN =item C<< ismatch_data_blks >> =item C<< num_max_ref_hits >> Max RefCount Hits =item C<> =item C<< num_stale_donors >> Stale Donor Count =item C<< num_files_too_small >> File Too Small Count =item C<< num_out_of_space_errors >> Num Out Of Space =item C<< num_mismatch_fps >> FP False Match =item C<< fp_mismatch_overwrites >> Mismatch Due To Overrides =item C<< num_deleted_ino_recs >> Delino Records =item C<< records_sorted >> =item C<< num_unaligned_compression_blocks >> Unaligned Compression Blocks =item C<< additional_sharing_messages >> Additional Sharing Messages =item C<< records_sorted >> Records Sorted =item C<< used_0_splits >> Used 0 Splits =item C<< used_1_split >> Used 1 Split =item C<< used_2_splits >> Used 2 Splits =item C<< used_1_pass >> Used 1 Pass =item C<< used_2_passes >> Used 2 Passes =item C<< used_3_passes >> Used 3 Passes =item C<< num_p1_merges >> Number Of P1 Merges =item C<< num_merged_bins >> Number Of Merged Bins =item C<< block_sharing_histo >> (Array) Block Sharing Histogram =item C<< block_sharing_average >> Average Chain Length =item C<< ref_count_histo >> (Array) Reference Count Histogram =item C<< ref_count_average >> Average Reference Count =item C<< unflushed_clogs >> Unflushed Changelogs =item C<< blks_saved_compression >> Blocks Saved By Compression =item C<< num_cg_decompressed >> Number of CGs Decompressed =item C<< num_partial_cg_modifies >> Partial CG Modifies =item C<< average_decompress_time >> Average Decompression Time =item C<< bufs_compression_processed >> Buffers Compression Processed =item C<< extra_cp_reads >> Extra CP Reads =item C<< num_compressed_inline >> CGs Compressed Inline =item C<< num_compressed_bg >> CGs Compressed =item C<< num_compressed_blks >> Compressed Blocks =item C<< num_uncompressed_blks >> Uncompressed Blocks =item C<< num_partial_cg_new_writes >> Partial CG New Writes =item C<< num_decompress_read_bad_blks >> Disk Bad Blocks =item C<< num_decompress_mark_sw_bad >> Compression Bad Blocks =item C<< avg_compress_cg_time >> Average Compression Time =item C<< num_compress_attempts >> Compression Attempts =item C<< num_compress_fail >> Compression Failures =item C<< num_not_enough_savings >> Poor Compression Ratio =item C<< num_shared_skipped >> Shared Blocks Skipped By Compression =item C<< num_snap_skipped >> Snapshot Blocks Skipped By Compression =item C<< row_status >> =item C<< total_space_saved >> =item C<< max_sis_proc >> (7Mode only) Max SIS Proc =item C<< max_share_blocks >> (7Mode only) Max Share Blocks =item C<> (7Mode only) Pending SIS Proc =item C<> (7Mode only) Running SIS Proc =item C<> (7Mode only) Total Configured =item C<> (7Mode only) Succeeded Op =item C<> (7Mode only) Started Op =item C<> (7Mode only) Failed Op =item C<> (7Mode only) Deffered Op =item C<> (7Mode only) Stopped Op =item C<> (7Mode only) Dropped Change Logs =item C<> (7Mode only) Change log generated =item C<> (7Mode only) Change log flushed =item C<> (7Mode only) Change log pending =item C<> (7Mode only) Max Sis Ops =item C<> (7Mode only) Pending Sis Ops =item C<> (7Mode only) Pending Sis Ops =item C<> (7Mode only) Runing Sis Ops =item C<> (7Mode only) Succeded Ops =item C<> (7Mode only) Started Ops =item C<> (7Mode only) Failed Ops =item C<> (7Mode only) defered Ops =item C<> (7Mode only) Stopped Ops =item C<> (7Mode only) Block Sharing Stats =item C<> (7Mode only) Locked Donor =item C<> (7Mode only) Locked Recepient =item C<> (7Mode only) BCMP in Exempt =item C<< avg_idd_qcheck_time >> Filled in for CMode CLI. =item C<< num_icg_inline >> Filled in for CMode CLI. =item C<< num_qcheck_fail >> Filled in for CMode CLI. =item C<< avg_cd_qcheck_time >> Filled in for CMode CLI. =item C<< bce_policy_stage >> Filled in for CMode CLI. =item C<< bce_err_post_processing_nospace >> Filled in for CMode CLI. =item C<< bce_post_processing_bdata_rejections >> Filled in for CMode CLI. =item C<< bce_err_nospace >> Filled in for CMode CLI. =item C<< bce_recieved_in_exempt >> Filled in for CMode CLI. =item C<< bce_err_post_processing_abort >> Filled in for CMode CLI. =item C<< bce_post_processing_stage >> Filled in for CMode CLI. =item C<< bce_sending_to_exempt >> Filled in for CMode CLI. =item C<< bce_err_abort >> Filled in for CMode CLI. =item C<< bce_fbn_invalid >> Filled in for CMode CLI. =item C<< bce_compress_stage >> Filled in for CMode CLI. =item C<< bce_err_post_processing_stale_inode >> Filled in for CMode CLI. =item C<< bce_err_stale_inode >> Filled in for CMode CLI. =item C<< num_compressed_bg_cg >> *Background Compressed CGs Filled in for CMode CLI. =item C<< num_skipshare_blocks_upper >> *Skip Share Blocks Upper Filled in for CMode CLI. =item C<< num_skipshare_blocks_delta >> *Skip Share Blocks Delta Filled in for CMode CLI. =item C<< num_vbn_zero_cg_skipped >> *CGs Skipped Due to VBN_ZERO Policy Filled in for CMode CLI. =item C<< unflushed_data_logs >> *Unflushed Data Logs Filled in for CMode CLI. =item C<< unflushed_ref_logs >> *Unflushed Ref Logs Filled in for CMode CLI. =item C<< bce_received_in_exempt >> *BCE Messages that are received in Exempt Domain Filled in for CMode CLI. =item C<< shared_references >> *Shared References Filled in for CMode CLI. =item C<< num_stale_aux_recipients >> *Stale Auxiliary Recipient Count 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 Shar Filled in for CMode CLI. =item C<< num_stale_aux_mismatch >> *Mismatched Recipient Block Pointers Filled in for CMode CLI. =item C<< same_sharing_records >> Same Sharing Records possible value(s) are, integer Filled in for CMode CLI. =item C<< bce_compress_stage_overwrites >> BCE CGs Skipped Due to Overwrites in Compress Stage Filled in for CMode CLI. =item C<< bce_post_processing_overwrites >> BCE CGs Skipped Due to Overwrites in Post Processing Filled in for CMode CLI. =item C<< avg_decomp_cg_count >> Average Number of CGs Batched for Decompression Filled in for CMode CLI. =item C<< num_vbn_absent >> VBN Absent Count Filled in for CMode CLI. =item C<< no_op_blocks >> No Op Filled in for CMode CLI. =back =cut package NACL::CS::VolumeEfficiencyStat; use strict; use warnings; use Params::Validate qw(validate); use NACL::ComponentUtils qw(_dump_one); use NATE::Log qw(log_global); my $Log = log_global(); my $may_enter = $Log->may_enter(); my $may_exit = $Log->may_exit(); use Data::Dumper; use NACL::Exceptions::NoElementsFound qw(:try); use base 'NACL::CS::ComponentState::ONTAP'; use Class::MethodMaker [ scalar => 'vserver', scalar => 'volume', scalar => 'path', scalar => 'b', scalar => 'g', scalar => 'allocated_data', scalar => 'shared_data', scalar => 'space_saved', scalar => 'saved_percentage', scalar => 'max_ref_count', scalar => 'total_processed_data', scalar => 'total_process_time', scalar => 'total_verify_time', scalar => 'num_sis_files', scalar => 'num_succeeded_ops', scalar => 'num_started_ops', scalar => 'num_failed_ops', scalar => 'num_stopped_ops', scalar => 'num_deferred_ops', scalar => 'num_check_ok_ops', scalar => 'num_check_fail_ops', scalar => 'num_check_susp_ops', scalar => 'num_fps_deleted', scalar => 'num_sorted_blocks', scalar => 'overlapped_blocks', scalar => 'same_fp_blocks', scalar => 'same_fbn_blocks', scalar => 'same_data_blocks', scalar => 'same_vbn_blocks', scalar => 'mismatch_data_blks', scalar => 'num_max_ref_hits', scalar => 'num_stale_recipients', scalar => 'num_stale_donors', scalar => 'num_files_too_small', scalar => 'num_out_of_space_errors', scalar => 'num_mismatch_fps', scalar => 'fp_mismatch_overwrites', scalar => 'num_deleted_ino_recs', scalar => 'records_sorted', scalar => 'used_0_splits', scalar => 'used_1_split', scalar => 'used_2_splits', scalar => 'used_1_pass', scalar => 'used_2_passes', scalar => 'used_3_passes', scalar => 'num_p1_merges', scalar => 'num_merged_bins', array => 'block_sharing_histo', scalar => 'block_sharing_average', array => 'ref_count_histo', scalar => 'ref_count_average', scalar => 'unflushed_clogs', scalar => 'blks_saved_compression', scalar => 'num_cg_decompressed', scalar => 'num_partial_cg_modifies', scalar => 'average_decompress_time', scalar => 'bufs_compression_processed', scalar => 'extra_cp_reads', scalar => 'num_compressed_inline', scalar => 'num_compressed_bg', scalar => 'num_compressed_blks', scalar => 'num_uncompressed_blks', scalar => 'num_partial_cg_new_writes', scalar => 'num_decompress_read_bad_blks', scalar => 'num_decompress_mark_sw_bad', scalar => 'avg_compress_cg_time', scalar => 'num_compress_attempts', scalar => 'num_compress_fail', scalar => 'num_not_enough_savings', scalar => 'num_shared_skipped', scalar => 'num_snap_skipped', scalar => 'row_status', scalar => 'num_unaligned_compression_blocks', scalar => 'additional_sharing_messages', scalar => 'total_space_saved', #The following fields are seen in sis stat -g scalar => 'max_sis_proc', scalar => 'max_share_blocks', scalar => 'pending_sis_proc', scalar => 'running_sis_proc', scalar => 'total_configured', scalar => 'succeeded_op', scalar => 'started_op', scalar => 'failed_op', scalar => 'deferred_op', scalar => 'stopped_op', scalar => 'dropped_change_logs', scalar => 'change_log_generated', scalar => 'change_log_flushed', scalar => 'change_log_pending', #The following are seen in more recent builds scalar => 'max_sis_ops', scalar => 'pending_sis_ops', scalar => 'running_sis_ops', scalar => 'succeeded_ops', scalar => 'started_ops', scalar => 'failed_ops', scalar => 'deferred_ops', scalar => 'stopped_ops', scalar => 'block_sharing_stats', scalar => 'locked_donor', scalar => 'locked_recipient', scalar => 'bcmp_in_exempt', scalar => 'avg_idd_qcheck_time', scalar => 'num_icg_inline', scalar => 'num_qcheck_fail', scalar => 'avg_cd_qcheck_time', scalar => 'bce_policy_stage', scalar => 'bce_err_post_processing_nospace', scalar => 'bce_post_processing_bdata_rejections', scalar => 'bce_err_nospace', scalar => 'bce_recieved_in_exempt', scalar => 'bce_err_post_processing_abort', scalar => 'bce_post_processing_stage', scalar => 'bce_sending_to_exempt', scalar => 'bce_err_abort', scalar => 'bce_fbn_invalid', scalar => 'bce_compress_stage', scalar => 'bce_err_post_processing_stale_inode', scalar => 'bce_err_stale_inode', scalar => 'num_compressed_bg_cg', scalar => 'num_skipshare_blocks_upper', scalar => 'num_skipshare_blocks_delta', scalar => 'num_vbn_zero_cg_skipped', scalar => 'unflushed_data_logs', scalar => 'unflushed_ref_logs', scalar => 'bce_received_in_exempt', scalar => 'shared_references', scalar => 'num_stale_aux_recipients', scalar => 'num_stale_aux_recipient_blocks', scalar => 'num_skipped_aux_sharing', scalar => 'num_stale_aux_mismatch', scalar => 'same_sharing_records', scalar => 'bce_compress_stage_overwrites', scalar => 'bce_post_processing_overwrites', scalar => 'avg_decomp_cg_count', scalar => 'num_vbn_absent', scalar => 'no_op_blocks', ]; =head1 METHODS =head2 fetch my $VolEfficiency_stat = NACL::CS::VolumeEfficiencyStat->fetch(command_interface => $ci, ...); my @VolEfficiency_stats = NACL::CS::VolumeEfficiencyStat->fetch(command_interface => $ci, ...); (Class method) Returns the statistics of Volume Efficiency operations in the form of a ComponentState object. 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. =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 stat', choices => [ { method => '_fetch_cmode_cli', interface => 'CLI', set => 'CMode', }, { method => '_fetch_7mode_cli', interface => 'CLI', set => '7Mode', } ], exception_text => 'No matching volume efficiency stat(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_stat'); $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_cmode_cli 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, $outputg, $outputl, %row, %output, @state_objs, %api_args, @out ); my $filter = $opts{filter}; my $requested_fields = $opts{requested_fields}; $api_args{path} = $filter->{path} if (exists($filter->{path})); # Check if any of the fields filled only with -l option my @fields_only_in_l = qw (max_ref_count total_processed_data total_verify_time num_sis_files num_succeeded_ops num_started_ops num_stopped_ops num_deferred_ops num_check_ok_ops num_check_fail_ops num_check_susp_ops num_fps_deleted num_sorted_blocks overlapped_blocks same_fp_blocks same_fpn_blocks same_data_blocks same_vbn_blocks num_failed_ops mismatch_data_blks num_max_ref_hits num_stale_recipients num_stale_donors num_files_too_small num_out_of_space_errors num_mismatch_fps fp_mismatch_overwrites num_deleted_ino_recs num_unaligned_compression_blocks additional_sharing_messages total_space_saved num_partial_cg_modifies num_partial_cg_new_writes average_decompress_time avg_compress_cg_time extra_cp_reads num_compressed_inline total_process_time); if ($pkg->_want_any_field_of( requested_fields => $requested_fields, filter => $filter, fields_filled_by_api => \@fields_only_in_l, ) ) { $Log->debug("The API 'sis_stat' will be invoked with -l option"); $api_args{verbose} = 1; } ## end if ( $pkg->_want_any_field_of... # Execute sis stat with only the options -l & collect ouput. try { $response = $apiset->sis_stat(%api_args); } catch NACL::APISet::Exceptions::InvalidParamValueException with { $caught_exception = 1; }; return if ($caught_exception); $outputl = $response->get_parsed_output(); # Check if any of the fields filled only when -g is passed my @fields_only_in_g = qw (max_sis_proc max_share_blocks pending_sis_proc running_sis_proc total_configured succeeded_op started_op failed_op deferred_op stopped_op dropped_change_logs change_log_generated change_log_flushed change_log_pending max_sis_ops pending_sis_ops running_sis_ops succeeded_ops started_ops failed_ops deferred_ops stopped_ops block_sharing_stats locked_donor locked_recipient bcmp_in_exempt); if ($pkg->_want_any_field_of( requested_fields => $requested_fields, filter => $filter, fields_filled_by_api => \@fields_only_in_g, ) ) { $Log->debug("The API 'sis_stat' will be invoked with -g option"); $api_args{'node-statistics'} = 1; } ## end if ( $pkg->_want_any_field_of... # Execute sis stat with only the options -l -g & collect ouput. $response = $apiset->sis_stat(%api_args); $outputg = $response->get_parsed_output(); ## Merging Two array of HASHes to one ######### ## If Tow arrays are like: ## array1 = [{parsed_output(sis stat -l vol1}, # {parsed_output(sis stat -l vol2}]; ## array = [{parsed_output(sis stat -l -g vol1}, # {parsed_output(sis stat -l -g vol2}]; ## The merged array will be: ## M_array = [{parsed_out((sis stat -l)+(sis stat -l -g) of vol1}, # {parsed_out((sis stat -l)+(sis stat -l -g) of vol2}]; # my $i = 0; foreach (@$outputl) { my %combo = (%$_, %{@$outputg[$i]}); push(@out, \%combo); $i++; } ## Merging Done ######### my @copy = ('path', @fields_only_in_g); foreach my $stat (@out) { my $final_attributes = $pkg->_hash_copy( source => $stat, copy => \@copy, map => { 'allocated' => 'allocated_data', 'shared' => 'shared_data', 'saving' => 'space_saved', '%saved' => 'saved_percentage', 'max_refcount' => 'max_ref_count', 'total_processed' => 'total_processed_data', 'total_process_time' => 'total_process_time', 'total_verify_time' => 'total_verify_time', 'sis_files' => 'num_sis_files', 'succeeded_op' => 'num_succeeded_ops', 'started_op' => 'num_started_ops', 'failed_op' => 'num_failed_ops', 'stopped_op' => 'num_stopped_ops', 'deferred_op' => 'num_deferred_ops', 'succeeded_check_op' => 'num_check_ok_ops', 'failed_check_op' => 'num_check_fail_ops', 'suspended_check_op' => 'num_check_susp_ops', 'total_fp_deleted' => 'num_fps_deleted', 'total_sorted_blocks' => 'num_sorted_blocks', 'overlapped_blocks' => 'overlapped_blocks', 'same_fingerprint' => 'same_fp_blocks', 'same_fbn_location' => 'same_fpn_blocks', 'same_data' => 'same_data_blocks', 'same_vbn' => 'same_vbn_blocks', 'mismatched_data' => 'mismatch_data_blks', 'max_reference_hits' => 'num_max_ref_hits', 'staled_recipient' => 'num_stale_recipients', 'staled_donor' => 'num_stale_donors', 'file_too_small' => 'num_files_too_small', 'out_of_space' => 'num_out_of_space_errors', 'fp_false_match' => 'num_mismatch_fps', 'mismatch_by_overwrite' => 'fp_mismatch_overwrites', 'delino_records' => 'num_deleted_ino_recs', 'unaligned_compression_blocks' => 'num_unaligned_compression_blocks', 'additional_sharing_messages' => 'additional_sharing_messages', 'compression_saved' => 'total_space_saved', 'cg_decompressed' => 'num_partial_cg_modifies', 'partial_cg_modifies' => 'num_partial_cg_new_writes', 'avg_decompress_time' => 'average_decompress_time', 'avg_compress_time' => 'avg_compress_cg_time', 'extra_cp_reads' => 'extra_cp_reads', 'inline_compression_attempts' => 'num_compressed_inline', 'background_compressed' => 'num_compressed_bg', 'compressed_walloced' => 'num_compressed_blks', 'uncompressed_walloced' => 'num_uncompressed_blks', 'new_partial_cg_writes' => 'num_partial_cg_new_writes', 'decompress_disk_bad' => 'num_decompress_mark_sw_bad', 'decompress_sw_bad' => 'num_decompress_mark_sw_bad', 'compress_attempts' => 'num_compress_attempts', 'compress_failed' => 'num_compress_fail', 'compress_low_savings' => 'num_not_enough_savings', 'snapshot_blocks_skipped' => 'num_snap_skipped', 'shared_blocks_skipped' => 'num_shared_skipped', 'un-flushed_changelogs' => 'unflushed_clogs', } ); my $obj = $pkg->new(); $obj->_set_fields(row => $final_attributes); push(@state_objs, $obj); } ## end foreach my $stat (@out) $Log->exit() if $may_exit; return @state_objs; } ## end sub _fetch_7mode_cli 1;