...

Source file src/github.com/shirou/gopsutil/disk/disk_solaris.go

Documentation: github.com/shirou/gopsutil/disk

     1  // +build solaris
     2  
     3  package disk
     4  
     5  import (
     6  	"bufio"
     7  	"context"
     8  	"fmt"
     9  	"math"
    10  	"os"
    11  	"strings"
    12  
    13  	"github.com/shirou/gopsutil/internal/common"
    14  	"golang.org/x/sys/unix"
    15  )
    16  
    17  const (
    18  	// _DEFAULT_NUM_MOUNTS is set to `cat /etc/mnttab | wc -l` rounded up to the
    19  	// nearest power of two.
    20  	_DEFAULT_NUM_MOUNTS = 32
    21  
    22  	// _MNTTAB default place to read mount information
    23  	_MNTTAB = "/etc/mnttab"
    24  )
    25  
    26  var (
    27  	// A blacklist of read-only virtual filesystems.  Writable filesystems are of
    28  	// operational concern and must not be included in this list.
    29  	fsTypeBlacklist = map[string]struct{}{
    30  		"ctfs":   struct{}{},
    31  		"dev":    struct{}{},
    32  		"fd":     struct{}{},
    33  		"lofs":   struct{}{},
    34  		"lxproc": struct{}{},
    35  		"mntfs":  struct{}{},
    36  		"objfs":  struct{}{},
    37  		"proc":   struct{}{},
    38  	}
    39  )
    40  
    41  func PartitionsWithContext(ctx context.Context, all bool) ([]PartitionStat, error) {
    42  	ret := make([]PartitionStat, 0, _DEFAULT_NUM_MOUNTS)
    43  
    44  	// Scan mnttab(4)
    45  	f, err := os.Open(_MNTTAB)
    46  	if err != nil {
    47  	}
    48  	defer func() {
    49  		if err == nil {
    50  			err = f.Close()
    51  		} else {
    52  			f.Close()
    53  		}
    54  	}()
    55  
    56  	scanner := bufio.NewScanner(f)
    57  	for scanner.Scan() {
    58  		fields := strings.Split(scanner.Text(), "\t")
    59  
    60  		if _, found := fsTypeBlacklist[fields[2]]; found {
    61  			continue
    62  		}
    63  
    64  		ret = append(ret, PartitionStat{
    65  			// NOTE(seanc@): Device isn't exactly accurate: from mnttab(4): "The name
    66  			// of the resource that has been mounted."  Ideally this value would come
    67  			// from Statvfs_t.Fsid but I'm leaving it to the caller to traverse
    68  			// unix.Statvfs().
    69  			Device:     fields[0],
    70  			Mountpoint: fields[1],
    71  			Fstype:     fields[2],
    72  			Opts:       fields[3],
    73  		})
    74  	}
    75  	if err := scanner.Err(); err != nil {
    76  		return nil, fmt.Errorf("unable to scan %q: %v", _MNTTAB, err)
    77  	}
    78  
    79  	return ret, err
    80  }
    81  
    82  func IOCountersWithContext(ctx context.Context, names ...string) (map[string]IOCountersStat, error) {
    83  	return nil, common.ErrNotImplementedError
    84  }
    85  
    86  func UsageWithContext(ctx context.Context, path string) (*UsageStat, error) {
    87  	statvfs := unix.Statvfs_t{}
    88  	if err := unix.Statvfs(path, &statvfs); err != nil {
    89  		return nil, fmt.Errorf("unable to call statvfs(2) on %q: %v", path, err)
    90  	}
    91  
    92  	usageStat := &UsageStat{
    93  		Path:   path,
    94  		Fstype: common.IntToString(statvfs.Basetype[:]),
    95  		Total:  statvfs.Blocks * statvfs.Frsize,
    96  		Free:   statvfs.Bfree * statvfs.Frsize,
    97  		Used:   (statvfs.Blocks - statvfs.Bfree) * statvfs.Frsize,
    98  
    99  		// NOTE: ZFS (and FreeBZSD's UFS2) use dynamic inode/dnode allocation.
   100  		// Explicitly return a near-zero value for InodesUsedPercent so that nothing
   101  		// attempts to garbage collect based on a lack of available inodes/dnodes.
   102  		// Similarly, don't use the zero value to prevent divide-by-zero situations
   103  		// and inject a faux near-zero value.  Filesystems evolve.  Has your
   104  		// filesystem evolved?  Probably not if you care about the number of
   105  		// available inodes.
   106  		InodesTotal:       1024.0 * 1024.0,
   107  		InodesUsed:        1024.0,
   108  		InodesFree:        math.MaxUint64,
   109  		InodesUsedPercent: (1024.0 / (1024.0 * 1024.0)) * 100.0,
   110  	}
   111  
   112  	usageStat.UsedPercent = (float64(usageStat.Used) / float64(usageStat.Total)) * 100.0
   113  
   114  	return usageStat, nil
   115  }
   116  

View as plain text