Update cgroups to 5933ab4dc4f7caa3a73a1dc141bd11f4
Signed-off-by: Michael Crosby <crosbymichael@gmail.com>
This commit is contained in:
parent
4c5ed9c068
commit
2ed3c62e27
@ -17,12 +17,12 @@ var cpuMetrics = []*metric{
|
||||
unit: metrics.Nanoseconds,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *cgroups.Metrics) []value {
|
||||
if stats.Cpu == nil {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Cpu.Usage.Total),
|
||||
v: float64(stats.CPU.Usage.Total),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -33,12 +33,12 @@ var cpuMetrics = []*metric{
|
||||
unit: metrics.Nanoseconds,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *cgroups.Metrics) []value {
|
||||
if stats.Cpu == nil {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Cpu.Usage.Kernel),
|
||||
v: float64(stats.CPU.Usage.Kernel),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -49,12 +49,12 @@ var cpuMetrics = []*metric{
|
||||
unit: metrics.Nanoseconds,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *cgroups.Metrics) []value {
|
||||
if stats.Cpu == nil {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Cpu.Usage.User),
|
||||
v: float64(stats.CPU.Usage.User),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -66,11 +66,11 @@ var cpuMetrics = []*metric{
|
||||
vt: prometheus.GaugeValue,
|
||||
labels: []string{"cpu"},
|
||||
getValues: func(stats *cgroups.Metrics) []value {
|
||||
if stats.Cpu == nil {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
var out []value
|
||||
for i, v := range stats.Cpu.Usage.PerCpu {
|
||||
for i, v := range stats.CPU.Usage.PerCPU {
|
||||
out = append(out, value{
|
||||
v: float64(v),
|
||||
l: []string{strconv.Itoa(i)},
|
||||
@ -85,12 +85,12 @@ var cpuMetrics = []*metric{
|
||||
unit: metrics.Total,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *cgroups.Metrics) []value {
|
||||
if stats.Cpu == nil {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Cpu.Throttling.Periods),
|
||||
v: float64(stats.CPU.Throttling.Periods),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -101,12 +101,12 @@ var cpuMetrics = []*metric{
|
||||
unit: metrics.Total,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *cgroups.Metrics) []value {
|
||||
if stats.Cpu == nil {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Cpu.Throttling.ThrottledPeriods),
|
||||
v: float64(stats.CPU.Throttling.ThrottledPeriods),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -117,12 +117,12 @@ var cpuMetrics = []*metric{
|
||||
unit: metrics.Nanoseconds,
|
||||
vt: prometheus.GaugeValue,
|
||||
getValues: func(stats *cgroups.Metrics) []value {
|
||||
if stats.Cpu == nil {
|
||||
if stats.CPU == nil {
|
||||
return nil
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Cpu.Throttling.ThrottledTime),
|
||||
v: float64(stats.CPU.Throttling.ThrottledTime),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -20,10 +20,10 @@ var hugetlbMetrics = []*metric{
|
||||
return nil
|
||||
}
|
||||
var out []value
|
||||
for page, v := range stats.Hugetlb {
|
||||
for _, v := range stats.Hugetlb {
|
||||
out = append(out, value{
|
||||
v: float64(v.Usage),
|
||||
l: []string{page},
|
||||
l: []string{v.Pagesize},
|
||||
})
|
||||
}
|
||||
return out
|
||||
@ -40,10 +40,10 @@ var hugetlbMetrics = []*metric{
|
||||
return nil
|
||||
}
|
||||
var out []value
|
||||
for page, v := range stats.Hugetlb {
|
||||
for _, v := range stats.Hugetlb {
|
||||
out = append(out, value{
|
||||
v: float64(v.Failcnt),
|
||||
l: []string{page},
|
||||
l: []string{v.Pagesize},
|
||||
})
|
||||
}
|
||||
return out
|
||||
@ -60,10 +60,10 @@ var hugetlbMetrics = []*metric{
|
||||
return nil
|
||||
}
|
||||
var out []value
|
||||
for page, v := range stats.Hugetlb {
|
||||
for _, v := range stats.Hugetlb {
|
||||
out = append(out, value{
|
||||
v: float64(v.Max),
|
||||
l: []string{page},
|
||||
l: []string{v.Pagesize},
|
||||
})
|
||||
}
|
||||
return out
|
||||
|
@ -36,7 +36,7 @@ var memoryMetrics = []*metric{
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.Rss),
|
||||
v: float64(stats.Memory.RSS),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -52,7 +52,7 @@ var memoryMetrics = []*metric{
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.RssHuge),
|
||||
v: float64(stats.Memory.RSSHuge),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -308,7 +308,7 @@ var memoryMetrics = []*metric{
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.TotalRss),
|
||||
v: float64(stats.Memory.TotalRSS),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -324,7 +324,7 @@ var memoryMetrics = []*metric{
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.TotalRssHuge),
|
||||
v: float64(stats.Memory.TotalRSSHuge),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -724,7 +724,7 @@ var memoryMetrics = []*metric{
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.KernelTcp.Failcnt),
|
||||
v: float64(stats.Memory.KernelTCP.Failcnt),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -740,7 +740,7 @@ var memoryMetrics = []*metric{
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.KernelTcp.Limit),
|
||||
v: float64(stats.Memory.KernelTCP.Limit),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -756,7 +756,7 @@ var memoryMetrics = []*metric{
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.KernelTcp.Max),
|
||||
v: float64(stats.Memory.KernelTCP.Max),
|
||||
},
|
||||
}
|
||||
},
|
||||
@ -772,7 +772,7 @@ var memoryMetrics = []*metric{
|
||||
}
|
||||
return []value{
|
||||
{
|
||||
v: float64(stats.Memory.KernelTcp.Usage),
|
||||
v: float64(stats.Memory.KernelTCP.Usage),
|
||||
},
|
||||
}
|
||||
},
|
||||
|
@ -123,7 +123,7 @@ func (c *Collector) Remove(id, namespace string) {
|
||||
delete(c.cgroups, taskID(id, namespace))
|
||||
}
|
||||
|
||||
func blkioValues(l []*cgroups.BlkioEntry) []value {
|
||||
func blkioValues(l []*cgroups.BlkIOEntry) []value {
|
||||
var out []value
|
||||
for _, e := range l {
|
||||
out = append(out, value{
|
||||
|
4
task.go
4
task.go
@ -119,6 +119,10 @@ type Task interface {
|
||||
// LoadProcess loads a previously created exec'd process
|
||||
LoadProcess(context.Context, string, IOAttach) (Process, error)
|
||||
// Metrics returns task metrics for runtime specific metrics
|
||||
//
|
||||
// The metric types are generic to containerd and change depending on the runtime
|
||||
// For the built in Linux runtime, github.com/containerd/cgroups.Metrics
|
||||
// are returned in protobuf format
|
||||
Metrics(context.Context) (*types.Metric, error)
|
||||
}
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
github.com/coreos/go-systemd 48702e0da86bd25e76cfef347e2adeb434a0d0a6
|
||||
github.com/containerd/go-runc ba22f6a82e52be3be4eb4a00000fe816f4b41c2e
|
||||
github.com/containerd/console 76d18fd1d66972718ab2284449591db0b3cdb4de
|
||||
github.com/containerd/cgroups 4be134fe43b9e207558365ad2675546b4910f696
|
||||
github.com/containerd/cgroups 5933ab4dc4f7caa3a73a1dc141bd11f42b5c9163
|
||||
github.com/docker/go-metrics 8fd5772bf1584597834c6f7961a530f06cbfbb87
|
||||
github.com/docker/go-events 9461782956ad83b30282bf90e31fa6a70c255ba9
|
||||
github.com/godbus/dbus c7fdd8b5cd55e87b4e1f4e372cdb1db61dd6c66f
|
||||
|
12
vendor/github.com/containerd/cgroups/blkio.go
generated
vendored
12
vendor/github.com/containerd/cgroups/blkio.go
generated
vendored
@ -57,7 +57,7 @@ func (b *blkioController) Update(path string, resources *specs.LinuxResources) e
|
||||
}
|
||||
|
||||
func (b *blkioController) Stat(path string, stats *Metrics) error {
|
||||
stats.Blkio = &BlkioStat{}
|
||||
stats.Blkio = &BlkIOStat{}
|
||||
settings := []blkioStatSettings{
|
||||
{
|
||||
name: "throttle.io_serviced",
|
||||
@ -119,7 +119,7 @@ func (b *blkioController) Stat(path string, stats *Metrics) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]*BlkioEntry) error {
|
||||
func (b *blkioController) readEntry(devices map[deviceKey]string, path, name string, entry *[]*BlkIOEntry) error {
|
||||
f, err := os.Open(filepath.Join(b.Path(path), fmt.Sprintf("blkio.%s", name)))
|
||||
if err != nil {
|
||||
return err
|
||||
@ -131,7 +131,7 @@ func (b *blkioController) readEntry(devices map[deviceKey]string, path, name str
|
||||
return err
|
||||
}
|
||||
// format: dev type amount
|
||||
fields := strings.FieldsFunc(sc.Text(), splitBlkioStatLine)
|
||||
fields := strings.FieldsFunc(sc.Text(), splitBlkIOStatLine)
|
||||
if len(fields) < 3 {
|
||||
if len(fields) == 2 && fields[0] == "Total" {
|
||||
// skip total line
|
||||
@ -158,7 +158,7 @@ func (b *blkioController) readEntry(devices map[deviceKey]string, path, name str
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*entry = append(*entry, &BlkioEntry{
|
||||
*entry = append(*entry, &BlkIOEntry{
|
||||
Device: devices[deviceKey{major, minor}],
|
||||
Major: major,
|
||||
Minor: minor,
|
||||
@ -235,7 +235,7 @@ type blkioSettings struct {
|
||||
|
||||
type blkioStatSettings struct {
|
||||
name string
|
||||
entry *[]*BlkioEntry
|
||||
entry *[]*BlkIOEntry
|
||||
}
|
||||
|
||||
func uintf(v interface{}) []byte {
|
||||
@ -257,7 +257,7 @@ func throttleddev(v interface{}) []byte {
|
||||
return []byte(fmt.Sprintf("%d:%d %d", td.Major, td.Minor, td.Rate))
|
||||
}
|
||||
|
||||
func splitBlkioStatLine(r rune) bool {
|
||||
func splitBlkIOStatLine(r rune) bool {
|
||||
return r == ' ' || r == ':'
|
||||
}
|
||||
|
||||
|
4
vendor/github.com/containerd/cgroups/cgroup.go
generated
vendored
4
vendor/github.com/containerd/cgroups/cgroup.go
generated
vendored
@ -166,9 +166,9 @@ func (c *cgroup) Stat(handlers ...ErrorHandler) (*Metrics, error) {
|
||||
}
|
||||
var (
|
||||
stats = &Metrics{
|
||||
Cpu: &CpuStat{
|
||||
CPU: &CPUStat{
|
||||
Throttling: &Throttle{},
|
||||
Usage: &CpuUsage{},
|
||||
Usage: &CPUUsage{},
|
||||
},
|
||||
}
|
||||
wg = &sync.WaitGroup{}
|
||||
|
6
vendor/github.com/containerd/cgroups/cpu.go
generated
vendored
6
vendor/github.com/containerd/cgroups/cpu.go
generated
vendored
@ -102,11 +102,11 @@ func (c *cpuController) Stat(path string, stats *Metrics) error {
|
||||
}
|
||||
switch key {
|
||||
case "nr_periods":
|
||||
stats.Cpu.Throttling.Periods = v
|
||||
stats.CPU.Throttling.Periods = v
|
||||
case "nr_throttled":
|
||||
stats.Cpu.Throttling.ThrottledPeriods = v
|
||||
stats.CPU.Throttling.ThrottledPeriods = v
|
||||
case "throttled_time":
|
||||
stats.Cpu.Throttling.ThrottledTime = v
|
||||
stats.CPU.Throttling.ThrottledTime = v
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
8
vendor/github.com/containerd/cgroups/cpuacct.go
generated
vendored
8
vendor/github.com/containerd/cgroups/cpuacct.go
generated
vendored
@ -43,10 +43,10 @@ func (c *cpuacctController) Stat(path string, stats *Metrics) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stats.Cpu.Usage.Total = total
|
||||
stats.Cpu.Usage.User = user
|
||||
stats.Cpu.Usage.Kernel = kernel
|
||||
stats.Cpu.Usage.PerCpu = percpu
|
||||
stats.CPU.Usage.Total = total
|
||||
stats.CPU.Usage.User = user
|
||||
stats.CPU.Usage.Kernel = kernel
|
||||
stats.CPU.Usage.PerCPU = percpu
|
||||
return nil
|
||||
}
|
||||
|
||||
|
7
vendor/github.com/containerd/cgroups/hugetlb.go
generated
vendored
7
vendor/github.com/containerd/cgroups/hugetlb.go
generated
vendored
@ -52,19 +52,20 @@ func (h *hugetlbController) Create(path string, resources *specs.LinuxResources)
|
||||
}
|
||||
|
||||
func (h *hugetlbController) Stat(path string, stats *Metrics) error {
|
||||
stats.Hugetlb = make(map[string]*HugetlbStat)
|
||||
for _, size := range h.sizes {
|
||||
s, err := h.readSizeStat(path, size)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stats.Hugetlb[size] = s
|
||||
stats.Hugetlb = append(stats.Hugetlb, s)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (h *hugetlbController) readSizeStat(path, size string) (*HugetlbStat, error) {
|
||||
var s HugetlbStat
|
||||
s := HugetlbStat{
|
||||
Pagesize: size,
|
||||
}
|
||||
for _, t := range []struct {
|
||||
name string
|
||||
value *uint64
|
||||
|
12
vendor/github.com/containerd/cgroups/memory.go
generated
vendored
12
vendor/github.com/containerd/cgroups/memory.go
generated
vendored
@ -91,7 +91,7 @@ func (m *memoryController) Stat(path string, stats *Metrics) error {
|
||||
Usage: &MemoryEntry{},
|
||||
Swap: &MemoryEntry{},
|
||||
Kernel: &MemoryEntry{},
|
||||
KernelTcp: &MemoryEntry{},
|
||||
KernelTCP: &MemoryEntry{},
|
||||
}
|
||||
if err := m.parseStats(f, stats.Memory); err != nil {
|
||||
return err
|
||||
@ -114,7 +114,7 @@ func (m *memoryController) Stat(path string, stats *Metrics) error {
|
||||
},
|
||||
{
|
||||
module: "kmem.tcp",
|
||||
entry: stats.Memory.KernelTcp,
|
||||
entry: stats.Memory.KernelTCP,
|
||||
},
|
||||
} {
|
||||
for _, tt := range []struct {
|
||||
@ -199,8 +199,8 @@ func (m *memoryController) parseStats(r io.Reader, stat *MemoryStat) error {
|
||||
line++
|
||||
}
|
||||
stat.Cache = raw["cache"]
|
||||
stat.Rss = raw["rss"]
|
||||
stat.RssHuge = raw["rss_huge"]
|
||||
stat.RSS = raw["rss"]
|
||||
stat.RSSHuge = raw["rss_huge"]
|
||||
stat.MappedFile = raw["mapped_file"]
|
||||
stat.Dirty = raw["dirty"]
|
||||
stat.Writeback = raw["writeback"]
|
||||
@ -216,8 +216,8 @@ func (m *memoryController) parseStats(r io.Reader, stat *MemoryStat) error {
|
||||
stat.HierarchicalMemoryLimit = raw["hierarchical_memory_limit"]
|
||||
stat.HierarchicalSwapLimit = raw["hierarchical_memsw_limit"]
|
||||
stat.TotalCache = raw["total_cache"]
|
||||
stat.TotalRss = raw["total_rss"]
|
||||
stat.TotalRssHuge = raw["total_rss_huge"]
|
||||
stat.TotalRSS = raw["total_rss"]
|
||||
stat.TotalRSSHuge = raw["total_rss_huge"]
|
||||
stat.TotalMappedFile = raw["total_mapped_file"]
|
||||
stat.TotalDirty = raw["total_dirty"]
|
||||
stat.TotalWriteback = raw["total_writeback"]
|
||||
|
4486
vendor/github.com/containerd/cgroups/metrics.pb.go
generated
vendored
4486
vendor/github.com/containerd/cgroups/metrics.pb.go
generated
vendored
File diff suppressed because it is too large
Load Diff
50
vendor/github.com/containerd/cgroups/metrics.proto
generated
vendored
50
vendor/github.com/containerd/cgroups/metrics.proto
generated
vendored
@ -1,19 +1,22 @@
|
||||
syntax = "proto3";
|
||||
|
||||
package cgroups;
|
||||
package io.containerd.cgroups.v1;
|
||||
|
||||
import "gogoproto/gogo.proto";
|
||||
|
||||
message Metrics {
|
||||
map<string, HugetlbStat> hugetlb = 1;
|
||||
repeated HugetlbStat hugetlb = 1;
|
||||
PidsStat pids = 2;
|
||||
CpuStat cpu = 3;
|
||||
CPUStat cpu = 3 [(gogoproto.customname) = "CPU"];
|
||||
MemoryStat memory = 4;
|
||||
BlkioStat blkio = 5;
|
||||
BlkIOStat blkio = 5;
|
||||
}
|
||||
|
||||
message HugetlbStat {
|
||||
uint64 usage = 1;
|
||||
uint64 max = 2;
|
||||
uint64 failcnt = 3;
|
||||
string pagesize = 4;
|
||||
}
|
||||
|
||||
message PidsStat {
|
||||
@ -21,17 +24,18 @@ message PidsStat {
|
||||
uint64 limit = 2;
|
||||
}
|
||||
|
||||
message CpuStat {
|
||||
CpuUsage usage = 1;
|
||||
message CPUStat {
|
||||
CPUUsage usage = 1;
|
||||
Throttle throttling = 2;
|
||||
}
|
||||
|
||||
message CpuUsage {
|
||||
message CPUUsage {
|
||||
// values in nanoseconds
|
||||
uint64 total = 1;
|
||||
uint64 kernel = 2;
|
||||
uint64 user = 3;
|
||||
repeated uint64 per_cpu = 4;
|
||||
repeated uint64 per_cpu = 4 [(gogoproto.customname) = "PerCPU"];
|
||||
|
||||
}
|
||||
|
||||
message Throttle {
|
||||
@ -42,8 +46,8 @@ message Throttle {
|
||||
|
||||
message MemoryStat {
|
||||
uint64 cache = 1;
|
||||
uint64 rss = 2;
|
||||
uint64 rss_huge = 3;
|
||||
uint64 rss = 2 [(gogoproto.customname) = "RSS"];
|
||||
uint64 rss_huge = 3 [(gogoproto.customname) = "RSSHuge"];
|
||||
uint64 mapped_file = 4;
|
||||
uint64 dirty = 5;
|
||||
uint64 writeback = 6;
|
||||
@ -59,8 +63,8 @@ message MemoryStat {
|
||||
uint64 hierarchical_memory_limit = 16;
|
||||
uint64 hierarchical_swap_limit = 17;
|
||||
uint64 total_cache = 18;
|
||||
uint64 total_rss = 19;
|
||||
uint64 total_rss_huge = 20;
|
||||
uint64 total_rss = 19 [(gogoproto.customname) = "TotalRSS"];
|
||||
uint64 total_rss_huge = 20 [(gogoproto.customname) = "TotalRSSHuge"];
|
||||
uint64 total_mapped_file = 21;
|
||||
uint64 total_dirty = 22;
|
||||
uint64 total_writeback = 23;
|
||||
@ -76,7 +80,7 @@ message MemoryStat {
|
||||
MemoryEntry usage = 33;
|
||||
MemoryEntry swap = 34;
|
||||
MemoryEntry kernel = 35;
|
||||
MemoryEntry kernel_tcp = 36;
|
||||
MemoryEntry kernel_tcp = 36 [(gogoproto.customname) = "KernelTCP"];
|
||||
|
||||
}
|
||||
|
||||
@ -87,18 +91,18 @@ message MemoryEntry {
|
||||
uint64 failcnt = 4;
|
||||
}
|
||||
|
||||
message BlkioStat {
|
||||
repeated BlkioEntry io_service_bytes_recursive = 1;
|
||||
repeated BlkioEntry io_serviced_recursive = 2;
|
||||
repeated BlkioEntry io_queued_recursive = 3;
|
||||
repeated BlkioEntry io_service_time_recursive = 4;
|
||||
repeated BlkioEntry io_wait_time_recursive = 5;
|
||||
repeated BlkioEntry io_merged_recursive = 6;
|
||||
repeated BlkioEntry io_time_recursive = 7;
|
||||
repeated BlkioEntry sectors_recursive = 8;
|
||||
message BlkIOStat {
|
||||
repeated BlkIOEntry io_service_bytes_recursive = 1;
|
||||
repeated BlkIOEntry io_serviced_recursive = 2;
|
||||
repeated BlkIOEntry io_queued_recursive = 3;
|
||||
repeated BlkIOEntry io_service_time_recursive = 4;
|
||||
repeated BlkIOEntry io_wait_time_recursive = 5;
|
||||
repeated BlkIOEntry io_merged_recursive = 6;
|
||||
repeated BlkIOEntry io_time_recursive = 7;
|
||||
repeated BlkIOEntry sectors_recursive = 8;
|
||||
}
|
||||
|
||||
message BlkioEntry {
|
||||
message BlkIOEntry {
|
||||
string op = 1;
|
||||
string device = 2;
|
||||
uint64 major = 3;
|
||||
|
Loading…
Reference in New Issue
Block a user