hunk.code_window: 			badDriver := "badDriverName"
   			th.App.Config().FileSettings.DriverName = &badDriver
  
hunk.labels: keep add keep
hunk.after_edit: 			defer func() {
   				th.App.Config().FileSettings.DriverName = oldDriver
   			}()
  
hunk.file_path: api4/system_test.go
hunk.type: add
file: // Copyright 2019 The Prometheus Authors
  // Licensed under the Apache License, Version 2.0 (the "License");
  // you may not use this file except in compliance with the License.
  // You may obtain a copy of the License at
  //
  // http://www.apache.org/licenses/LICENSE-2.0
  //
  // Unless required by applicable law or agreed to in writing, software
  // distributed under the License is distributed on an "AS IS" BASIS,
  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  // See the License for the specific language governing permissions and
  // limitations under the License.
  
  package procfs
  
  import (
  	"bufio"
  	"bytes"
  	"errors"
  	"regexp"
  
  	"github.com/prometheus/procfs/internal/util"
  )
  
  // Regexp variables
  var (
  	rPos          = regexp.MustCompile(`^pos:\s+(\d+)$`)
  	rFlags        = regexp.MustCompile(`^flags:\s+(\d+)$`)
  	rMntID        = regexp.MustCompile(`^mnt_id:\s+(\d+)$`)
  	rInotify      = regexp.MustCompile(`^inotify`)
  	rInotifyParts = regexp.MustCompile(`^inotify\s+wd:([0-9a-f]+)\s+ino:([0-9a-f]+)\s+sdev:([0-9a-f]+)(?:\s+mask:([0-9a-f]+))?`)
  )
  
  // ProcFDInfo contains represents file descriptor information.
  type ProcFDInfo struct {
  	// File descriptor
  	FD string
  	// File offset
  	Pos string
  	// File access mode and status flags
  	Flags string
  	// Mount point ID
  	MntID string
  	// List of inotify lines (structured) in the fdinfo file (kernel 3.8+ only)
  	InotifyInfos []InotifyInfo
  }
  
  // FDInfo constructor. On kernels older than 3.8, InotifyInfos will always be empty.
  func (p Proc) FDInfo(fd string) (*ProcFDInfo, error) {
  	data, err := util.ReadFileNoStat(p.path("fdinfo", fd))
  	if err != nil {
  		return nil, err
  	}
  
  	var text, pos, flags, mntid string
  	var inotify []InotifyInfo
  
  	scanner := bufio.NewScanner(bytes.NewReader(data))
  	for scanner.Scan() {
  		text = scanner.Text()
  		if rPos.MatchString(text) {
  			pos = rPos.FindStringSubmatch(text)[1]
  		} else if rFlags.MatchString(text) {
  			flags = rFlags.FindStringSubmatch(text)[1]
  		} else if rMntID.MatchString(text) {
  			mntid = rMntID.FindStringSubmatch(text)[1]
  		} else if rInotify.MatchString(text) {
  			newInotify, err := parseInotifyInfo(text)
  			if err != nil {
  				return nil, err
  			}
  			inotify = append(inotify, *newInotify)
  		}
  	}
  
  	i := &ProcFDInfo{
  		FD:           fd,
  		Pos:          pos,
  		Flags:        flags,
  		MntID:        mntid,
  		InotifyInfos: inotify,
  	}
  
  	return i, nil
  }
  
  // InotifyInfo represents a single inotify line in the fdinfo file.
  type InotifyInfo struct {
  	// Watch descriptor number
  	WD string
  	// Inode number
  	Ino string
  	// Device ID
  	Sdev string
  	// Mask of events being monitored
  	Mask string
  }
  
  // InotifyInfo constructor. Only available on kernel 3.8+.
  func parseInotifyInfo(line string) (*InotifyInfo, error) {
  	m := rInotifyParts.FindStringSubmatch(line)
  	if len(m) >= 4 {
  		var mask string
  		if len(m) == 5 {
  			mask = m[4]
  		}
  		i := &InotifyInfo{
  			WD:   m[1],
  			Ino:  m[2],
  			Sdev: m[3],
  			Mask: mask,
  		}
  		return i, nil
  	}
  	return nil, errors.New("invalid inode entry: " + line)
  }
  
  // ProcFDInfos represents a list of ProcFDInfo structs.
  type ProcFDInfos []ProcFDInfo
  
  func (p ProcFDInfos) Len() int           { return len(p) }
  func (p ProcFDInfos) Swap(i, j int)      { p[i], p[j] = p[j], p[i] }
  func (p ProcFDInfos) Less(i, j int) bool { return p[i].FD < p[j].FD }
  
  // InotifyWatchLen returns the total number of inotify watches
  func (p ProcFDInfos) InotifyWatchLen() (int, error) {
  	length := 0
  	for _, f := range p {
  		length += len(f.InotifyInfos)
  	}
  
  	return length, nil
  }
  