<s> import array <EOL> from collections import defaultdict <EOL> import fcntl <EOL> import itertools <EOL> import os <EOL> import struct <EOL> import psutil <EOL> from checks import AgentCheck <EOL> MIXED = "<STR_LIT>" <EOL> DATA = "<STR_LIT:data>" <EOL> METADATA = "<STR_LIT>" <EOL> SYSTEM = "<STR_LIT>" <EOL> SINGLE = "<STR_LIT>" <EOL> RAID0 = "<STR_LIT>" <EOL> RAID1 = "<STR_LIT>" <EOL> RAID10 = "<STR_LIT>" <EOL> DUP = "<STR_LIT>" <EOL> UNKNOWN = "<STR_LIT>" <EOL> FLAGS_MAPPER = defaultdict ( lambda : ( SINGLE , UNKNOWN ) , { <EOL> <NUM_LIT:1> : ( SINGLE , DATA ) , <EOL> <NUM_LIT:2> : ( SINGLE , SYSTEM ) , <EOL> <NUM_LIT:4> : ( SINGLE , METADATA ) , <EOL> <NUM_LIT:5> : ( SINGLE , MIXED ) , <EOL> <NUM_LIT:9> : ( RAID0 , DATA ) , <EOL> <NUM_LIT:10> : ( RAID0 , SYSTEM ) , <EOL> <NUM_LIT:12> : ( RAID0 , METADATA ) , <EOL> <NUM_LIT> : ( RAID0 , MIXED ) , <EOL> <NUM_LIT> : ( RAID1 , DATA ) , <EOL> <NUM_LIT> : ( RAID1 , SYSTEM ) , <EOL> <NUM_LIT:20> : ( RAID1 , METADATA ) , <EOL> <NUM_LIT> : ( RAID1 , MIXED ) , <EOL> <NUM_LIT> : ( DUP , DATA ) , <EOL> <NUM_LIT> : ( DUP , SYSTEM ) , <EOL> <NUM_LIT> : ( DUP , METADATA ) , <EOL> <NUM_LIT> : ( DUP , MIXED ) , <EOL> <NUM_LIT> : ( RAID10 , DATA ) , <EOL> <NUM_LIT> : ( RAID10 , SYSTEM ) , <EOL> <NUM_LIT> : ( RAID10 , METADATA ) , <EOL> <NUM_LIT> : ( RAID10 , MIXED ) , <EOL> } ) <EOL> BTRFS_IOC_SPACE_INFO = <NUM_LIT> <EOL> TWO_LONGS_STRUCT = struct . Struct ( "<STR_LIT>" ) <EOL> THREE_LONGS_STRUCT = struct . Struct ( "<STR_LIT>" ) <EOL> def sized_array ( count ) : <EOL> return array . array ( "<STR_LIT:B>" , itertools . repeat ( <NUM_LIT:0> , count ) ) <EOL> class FileDescriptor ( object ) : <EOL> def __init__ ( self , mountpoint ) : <EOL> self . fd = os . open ( mountpoint , os . O_DIRECTORY ) <EOL> def __enter__ ( self ) : <EOL> return self <EOL> def __exit__ ( self , exc_type , exc_value , traceback ) : <EOL> os . close ( self . fd ) <EOL> def fileno ( self ) : <EOL> return self . fd <EOL> def open ( self , dir ) : <EOL> return self . fd <EOL> class BTRFS ( AgentCheck ) : <EOL> def __init__ ( self , name , init_config , agentConfig , instances = None ) : <EOL> AgentCheck . __init__ ( self , name , init_config , agentConfig , instances = instances ) <EOL> if instances is not None and len ( instances ) > <NUM_LIT:1> : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> def get_usage ( self , mountpoint ) : <EOL> results = [ ] <EOL> with FileDescriptor ( mountpoint ) as fd : <EOL> ret = sized_array ( TWO_LONGS_STRUCT . size ) <EOL> fcntl . ioctl ( fd , BTRFS_IOC_SPACE_INFO , ret ) <EOL> _ , total_spaces = TWO_LONGS_STRUCT . unpack ( ret ) <EOL> buffer_size = ( TWO_LONGS_STRUCT . size <EOL> + total_spaces * THREE_LONGS_STRUCT . size ) <EOL> data = sized_array ( buffer_size ) <EOL> TWO_LONGS_STRUCT . pack_into ( data , <NUM_LIT:0> , total_spaces , <NUM_LIT:0> ) <EOL> fcntl . ioctl ( fd , BTRFS_IOC_SPACE_INFO , data ) <EOL> _ , total_spaces = TWO_LONGS_STRUCT . unpack_from ( ret , <NUM_LIT:0> ) <EOL> for offset in xrange ( TWO_LONGS_STRUCT . size , <EOL> buffer_size , <EOL> THREE_LONGS_STRUCT . size ) : <EOL> flags , total_bytes , used_bytes = THREE_LONGS_STRUCT . unpack_from ( data , offset ) <EOL> results . append ( ( flags , total_bytes , used_bytes ) ) <EOL> return results <EOL> def check ( self , instance ) : <EOL> btrfs_devices = { } <EOL> excluded_devices = instance . get ( '<STR_LIT>' , [ ] ) <EOL> for p in psutil . disk_partitions ( ) : <EOL> if ( p . fstype == '<STR_LIT>' and p . device not in btrfs_devices <EOL> and p . device not in excluded_devices ) : <EOL> btrfs_devices [ p . device ] = p . mountpoint <EOL> if len ( btrfs_devices ) == <NUM_LIT:0> : <EOL> raise Exception ( "<STR_LIT>" ) <EOL> for device , mountpoint in btrfs_devices . iteritems ( ) : <EOL> for flags , total_bytes , used_bytes in self . get_usage ( mountpoint ) : <EOL> replication_type , usage_type = FLAGS_MAPPER [ flags ] <EOL> tags = [ <EOL> '<STR_LIT>' . format ( usage_type ) , <EOL> '<STR_LIT>' . format ( replication_type ) , <EOL> ] <EOL> free = total_bytes - used_bytes <EOL> usage = float ( free ) / float ( total_bytes ) <EOL> self . gauge ( '<STR_LIT>' , total_bytes , tags = tags , device_name = device ) <EOL> self . gauge ( '<STR_LIT>' , used_bytes , tags = tags , device_name = device ) <EOL> self . gauge ( '<STR_LIT>' , free , tags = tags , device_name = device ) <EOL> self . gauge ( '<STR_LIT>' , usage , tags = tags , device_name = device ) </s>
