func (m *MajorMinor) Decode(in []byte, conf config.Decoder) ([]byte, error) {
	if m.cache == nil {
		m.cache = map[uint64][]byte{}
	}
	num := uint64(bcc.GetHostByteOrder().Uint32(in[0:4]))
	if _, ok := m.cache[num]; !ok {
		fd, err := os.Open(partitions)
		if err != nil {
			return nil, err
		}
		defer func() {
			if err = fd.Close(); err != nil {
				log.Printf("Error closing %s: %s", partitions, err)
			}
		}()
		major := unix.Major(num)
		minor := unix.Minor(num)
		name := []byte(majorMinorToName(major, minor, fd))
		if len(name) == 0 {
			return []byte(fmt.Sprintf("unknown:%d:%d", major, minor)), nil
		}
		m.cache[num] = name
	}
	return m.cache[num], nil
}
Decode transforms minormajor device id into device name like sda2
package decoder
import (
	"bufio"
	"fmt"
	"io"
	"log"
	"os"
	"strconv"
	"strings"
	"github.com/cloudflare/ebpf_exporter/config"
	"github.com/iovisor/gobpf/bcc"
	"golang.org/x/sys/unix"
)
const (
	partitions = "/proc/partitions"
)
type MajorMinor struct {
	cache map[uint64][]byte
}