[v9,01/15] sysctl: add CTL_FLAGS_HAS to mark successful sysctl_op request

Submitted by Pavel Tikhomirov on May 10, 2016, 7:57 a.m.

Details

Message ID 1462867077-13746-1-git-send-email-ptikhomirov@virtuozzo.com
State Accepted
Series "net/ipv6: c/r dev/default/all conf ops"
Commit 041e48b544309e6d731bbd58de507d72cea13400
Headers show

Commit Message

Pavel Tikhomirov May 10, 2016, 7:57 a.m.
v4: replace separate has pointer to CTL_FLAGS_HAS flag, second part in
patch "net/ipv4: add net_conf_op to reuse for ipv6"
v6: define CTL_FLAGS_HAS
v7: also allow EIO on do_sysctl_op for optional sysctls like
stable_secret and fix sysctl file to close in error path
v9: add CTL_FLAGS_READ_EIO_SKIP to skip dumping stable_secret on EIO

https://jira.sw.ru/browse/PSBM-30942

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
---
 criu/include/sysctl.h |  2 ++
 criu/sysctl.c         | 21 +++++++++++++++++----
 2 files changed, 19 insertions(+), 4 deletions(-)

Patch hide | download patch | download mbox

diff --git a/criu/include/sysctl.h b/criu/include/sysctl.h
index b949a40..e271f5e 100644
--- a/criu/include/sysctl.h
+++ b/criu/include/sysctl.h
@@ -35,5 +35,7 @@  enum {
  * Some entries might be missing mark them as optional.
  */
 #define CTL_FLAGS_OPTIONAL	1
+#define CTL_FLAGS_HAS		2
+#define CTL_FLAGS_READ_EIO_SKIP	4
 
 #endif /* __CR_SYSCTL_H__ */
diff --git a/criu/sysctl.c b/criu/sysctl.c
index 21ae4ce..5fced0e 100644
--- a/criu/sysctl.c
+++ b/criu/sysctl.c
@@ -303,8 +303,13 @@  static int __userns_sysctl_op(void *arg, int proc_fd, pid_t pid)
 		close(nsfd);
 
 		for (i = 0; i < userns_req->nr_req; i++) {
-			if (do_sysctl_op(fds[i], reqs[i], op) < 0)
-				exit(1);
+			if (do_sysctl_op(fds[i], reqs[i], op) < 0) {
+				if (op != CTL_READ || errno != EIO || !(req->flags & CTL_FLAGS_READ_EIO_SKIP))
+					exit(1);
+			} else {
+				/* mark sysctl in question exists */
+				req->flags |= CTL_FLAGS_HAS;
+			}
 		}
 
 		exit(0);
@@ -372,8 +377,16 @@  static int __nonuserns_sysctl_op(struct sysctl_req *req, size_t nr_req, int op)
 		}
 
 		ret = do_sysctl_op(fd, req, op);
-		if (ret)
-			goto out;
+		if (ret) {
+			if (op != CTL_READ || errno != EIO || !(req->flags & CTL_FLAGS_READ_EIO_SKIP)) {
+				close(fd);
+				goto out;
+			}
+		} else {
+			/* mark sysctl in question exists */
+			req->flags |= CTL_FLAGS_HAS;
+		}
+
 		close(fd);
 		req++;
 	}