func()

in image/resources/knfsd-metrics-agent/internal/mounts/scraper.go [200:252]


func (agg nfsStatsAggregator) AddMount(blkid string, mount *procfs.Mount) {
	stats, ok := mount.Stats.(*procfs.MountStatsNFS)
	if !ok {
		return
	}

	server, _ := splitNFSDevice(mount.Device)

	grp, found := agg[server]
	if !found {
		grp = nfsStatsGroup{
			nfsStats: nfsStats{
				server: server,
			},
			localPaths: make(stringSet),
			blockIDs:   make(stringSet),
		}
		agg[server] = grp
	}

	// Always track the local path in case the same remote export has multiple
	// local mounts.
	grp.localPaths.Add(mount.Mount)

	// Check if this mount shares the same io_stats as a previous mount
	//
	// Although the NFS stats are reported per mount multiple mounts can share
	// the same io_stats record in the kernel.
	//
	// When multiple mounts share the same io_stats record, the same stats will
	// be reported multiple times, once for each mount sharing the io_stats
	// record.
	//
	// If these duplicated stats are added together then the stats will
	// effectively be multiplied by the number of mounts sharing the same
	// io_stats record.
	//
	// In the kernel source, io_stats is a member of nfs_server, and nfs_server
	// has a 1:1 correlation with super_block. Each NFS super_block is allocated
	// a virtual block device ID using the get_anon_bdev function.
	//
	// NOTE: Multiple, nfs_server records can share the same RPC client, so its
	// possible (and common) for multiple mounts to have separate io_stats but
	// share the same RPC clients. The RPC clients are denoted by the xprt lines
	// in mountstats (procfs.NFSTransportStats).
	if grp.blockIDs.Contains(blkid) {
		return
	}

	grp.blockIDs.Add(blkid)
	grp.summary = addSummary(newSummary(stats), grp.summary)
	agg[server] = grp
}