Package: lxcfs / 4.0.7-1

0001-proc_cpuview-release-lock-before-returning.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
From 725e90b5d67e264ee4a7ff0851c79728feab1da8 Mon Sep 17 00:00:00 2001
From: Christian Brauner <christian.brauner@ubuntu.com>
Date: Thu, 28 Jan 2021 11:07:16 +0100
Subject: [PATCH] proc_cpuview: release lock before returning

Fixes: #442
Cc: stable-4.0
Signed-off-by: Christian Brauner <christian.brauner@ubuntu.com>
---
 src/proc_cpuview.c | 54 +++++++++++++++++++++++++++++++++-------------
 1 file changed, 39 insertions(+), 15 deletions(-)

diff --git a/src/proc_cpuview.c b/src/proc_cpuview.c
index c5bf9f9..aaa3f53 100644
--- a/src/proc_cpuview.c
+++ b/src/proc_cpuview.c
@@ -315,7 +315,8 @@ static struct cg_proc_stat *find_proc_stat_node(struct cg_proc_stat_head *head,
 	return node;
 }
 
-static struct cg_proc_stat *find_or_create_proc_stat_node(struct cpuacct_usage *usage, int cpu_count, const char *cg)
+static struct cg_proc_stat *find_or_create_proc_stat_node(struct cpuacct_usage *usage,
+							  int cpu_count, const char *cg)
 {
 	int hash = calc_hash(cg) % CPUVIEW_HASH_SIZE;
 	struct cg_proc_stat_head *head = proc_stat_history[hash];
@@ -605,6 +606,7 @@ int cpuview_proc_stat(const char *cg, const char *cpuset,
 	if (max_cpus > cpu_cnt || !max_cpus)
 		max_cpus = cpu_cnt;
 
+	/* takes lock pthread_mutex_lock(&node->lock) */
 	stat_node = find_or_create_proc_stat_node(cg_cpu_usage, nprocs, cg);
 	if (!stat_node)
 		return log_error(0, "Failed to find/create stat node for %s", cg);
@@ -760,8 +762,11 @@ int cpuview_proc_stat(const char *cg, const char *cpuset,
 		     "cpu  %" PRIu64 " 0 %" PRIu64 " %" PRIu64 " 0 0 0 0 0 0\n",
 		     user_sum, system_sum, idle_sum);
 	lxcfs_v("cpu-all: %s\n", buf);
-	if (l < 0)
-		return log_error(0, "Failed to write cache");
+	if (l < 0) {
+		lxcfs_error("Failed to write cache");
+		total_len = 0;
+		goto out_pthread_mutex_unlock;
+	}
 	if (l >= buf_size)
 		return log_error(0, "Write to cache was truncated");
 
@@ -785,10 +790,16 @@ int cpuview_proc_stat(const char *cg, const char *cpuset,
 			     stat_node->view[curcpu].system,
 			     stat_node->view[curcpu].idle);
 		lxcfs_v("cpu: %s\n", buf);
-		if (l < 0)
-			return log_error(0, "Failed to write cache");
-		if (l >= buf_size)
-			return log_error(0, "Write to cache was truncated");
+		if (l < 0) {
+			lxcfs_error("Failed to write cache");
+			total_len = 0;
+			goto out_pthread_mutex_unlock;
+		}
+		if (l >= buf_size) {
+			lxcfs_error("Write to cache was truncated");
+			total_len = 0;
+			goto out_pthread_mutex_unlock;
+		}
 
 		buf += l;
 		buf_size -= l;
@@ -797,10 +808,16 @@ int cpuview_proc_stat(const char *cg, const char *cpuset,
 
 	/* Pass the rest of /proc/stat, start with the last line read */
 	l = snprintf(buf, buf_size, "%s", line);
-	if (l < 0)
-		return log_error(0, "Failed to write cache");
-	if (l >= buf_size)
-		return log_error(0, "Write to cache was truncated");
+	if (l < 0) {
+		lxcfs_error("Failed to write cache");
+		total_len = 0;
+		goto out_pthread_mutex_unlock;
+	}
+	if (l >= buf_size) {
+		lxcfs_error("Write to cache was truncated");
+		total_len = 0;
+		goto out_pthread_mutex_unlock;
+	}
 
 	buf += l;
 	buf_size -= l;
@@ -809,16 +826,23 @@ int cpuview_proc_stat(const char *cg, const char *cpuset,
 	/* Pass the rest of the host's /proc/stat */
 	while (getline(&line, &linelen, f) != -1) {
 		l = snprintf(buf, buf_size, "%s", line);
-		if (l < 0)
-			return log_error(0, "Failed to write cache");
-		if (l >= buf_size)
-			return log_error(0, "Write to cache was truncated");
+		if (l < 0) {
+			lxcfs_error("Failed to write cache");
+			total_len = 0;
+			goto out_pthread_mutex_unlock;
+		}
+		if (l >= buf_size) {
+			lxcfs_error("Write to cache was truncated");
+			total_len = 0;
+			goto out_pthread_mutex_unlock;
+		}
 
 		buf += l;
 		buf_size -= l;
 		total_len += l;
 	}
 
+out_pthread_mutex_unlock:
 	if (stat_node)
 		pthread_mutex_unlock(&stat_node->lock);