1// Copyright 2019 The Prometheus Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package iscsi
16
17import (
18	"path/filepath"
19	"strings"
20
21	"github.com/prometheus/procfs/internal/fs"
22)
23
24// iscsi target started with /sys/kernel/config/target/iscsi/iqn*
25// configfs + target/iscsi/iqn*
26// iqnGlob is representing all the possible IQN
27const iqnGlob = "target/iscsi/iqn*"
28
29// targetCore static path /sys/kernel/config/target/core for node_exporter
30// reading runtime status
31const targetCore = "target/core"
32
33// devicePath static path /sys/devices/rbd/[0-9]* for rbd devices to
34// read at runtime status
35const devicePath = "devices/rbd"
36
37// FS represents the pseudo-filesystem configfs, which provides an interface to
38// iscsi kernel data structures in
39// sysfs	as /sys
40// configfs as /sys/kernel/config
41type FS struct {
42	sysfs    *fs.FS
43	configfs *fs.FS
44}
45
46// NewFS returns a new configfs mounted under the given mount point. It will
47// error and return empty FS if the mount point can't be read. For the ease of
48// use, an empty string parameter configfsMountPoint will call internal fs for
49// the default sys path as /sys/kernel/config
50func NewFS(sysfsPath string, configfsMountPoint string) (FS, error) {
51	if strings.TrimSpace(sysfsPath) == "" {
52		sysfsPath = fs.DefaultSysMountPoint
53	}
54	sysfs, err := fs.NewFS(sysfsPath)
55	if err != nil {
56		return FS{}, err
57	}
58	if strings.TrimSpace(configfsMountPoint) == "" {
59		configfsMountPoint = fs.DefaultConfigfsMountPoint
60	}
61	configfs, err := fs.NewFS(configfsMountPoint)
62	if err != nil {
63		return FS{}, err
64	}
65	return FS{&sysfs, &configfs}, nil
66}
67
68// helper function to get configfs path
69func (fs FS) Path(p ...string) string {
70	return fs.configfs.Path(p...)
71}
72
73// ISCSIStats getting iscsi runtime information
74func (fs FS) ISCSIStats() ([]*Stats, error) {
75	matches, err := filepath.Glob(fs.configfs.Path(iqnGlob))
76	if err != nil {
77		return nil, err
78	}
79
80	stats := make([]*Stats, 0, len(matches))
81	for _, iqnPath := range matches {
82		// stats
83		s, err := GetStats(iqnPath)
84		if err != nil {
85			return nil, err
86		}
87		stats = append(stats, s)
88	}
89
90	return stats, nil
91}
92
93// TPGT struct for sys target portal group tag info
94type TPGT struct {
95	Name     string // name of the tpgt group
96	TpgtPath string // file path of tpgt
97	IsEnable bool   // is the tpgt enable
98	Luns     []LUN  // the Luns that tpgt has
99}
100
101// LUN struct for sys logical unit number info
102type LUN struct {
103	Name       string // name of the lun
104	LunPath    string // file path of the lun
105	Backstore  string // backstore of the lun
106	ObjectName string // place holder for object
107	TypeNumber string // place holder for number of the device
108}
109
110// FILEIO struct for backstore info
111type FILEIO struct {
112	Name       string // name of the fileio
113	Fnumber    string // number related to the backstore
114	ObjectName string // place holder for object in iscsi object
115	Filename   string // link to the actual file being export
116}
117
118// IBLOCK struct for backstore info
119type IBLOCK struct {
120	Name       string // name of the iblock
121	Bnumber    string // number related to the backstore
122	ObjectName string // place holder for object in iscsi object
123	Iblock     string // link to the actual block being export
124}
125
126// RBD struct for backstore info
127type RBD struct {
128	Name    string // name of the rbd
129	Rnumber string // number related to the backstore
130	Pool    string // place holder for the rbd pool
131	Image   string // place holder for the rbd image
132}
133
134// RDMCP struct for backstore info
135type RDMCP struct {
136	Name       string // name of the rdm_cp
137	ObjectName string // place holder for object name
138}
139
140// Stats struct for all targets info
141type Stats struct {
142	Name     string
143	Tpgt     []TPGT
144	RootPath string
145}
146