[CRIU] [PATCH] Add sysctl handling engine
Cyrill Gorcunov
gorcunov at openvz.org
Thu Feb 2 10:57:29 EST 2012
Since we need to operate with sysctls pretty heavy,
better to add some common engine for all handlers.
Based-on-patch-from: Pavel Emelyanov <xemul at parallels.com>
Signed-off-by: Cyrill Gorcunov <gorcunov at openvz.org>
---
Makefile | 1 +
include/image.h | 4 +-
include/sysctl.h | 33 ++++++
ipc_ns.c | 303 +++++-------------------------------------------------
sysctl.c | 216 ++++++++++++++++++++++++++++++++++++++
uts_ns.c | 66 ++++++-------
6 files changed, 310 insertions(+), 313 deletions(-)
create mode 100644 include/sysctl.h
create mode 100644 sysctl.c
diff --git a/Makefile b/Makefile
index 3990e2c..093de51 100644
--- a/Makefile
+++ b/Makefile
@@ -35,6 +35,7 @@ OBJS += cr-dump.o
OBJS += cr-show.o
OBJS += util.o
OBJS += util-net.o
+OBJS += sysctl.o
OBJS += ptrace.o
OBJS += log.o
OBJS += libnetlink.o
diff --git a/include/image.h b/include/image.h
index 59e91a6..8e6a000 100644
--- a/include/image.h
+++ b/include/image.h
@@ -111,8 +111,8 @@ struct ipc_ns_entry {
u32 msg_ctlmnb;
u32 msg_ctlmni;
u32 auto_msgmni;
- u32 shm_ctlmax[2];
- u64 shm_ctlall[2];
+ u64 shm_ctlmax;
+ u64 shm_ctlall;
u32 shm_ctlmni;
u32 shm_rmid_forced;
u32 mq_queues_max;
diff --git a/include/sysctl.h b/include/sysctl.h
new file mode 100644
index 0000000..0d67b21
--- /dev/null
+++ b/include/sysctl.h
@@ -0,0 +1,33 @@
+#ifndef CR_SYSCTL_H_
+#define CR_SYSCTL_H_
+
+struct sysctl_req {
+ char *name;
+ void *arg;
+ int type;
+};
+
+extern int sysctl_op(struct sysctl_req *req, int op);
+
+enum {
+ CTL_READ,
+ CTL_WRITE,
+ CTL_PRINT,
+};
+
+#define CTL_SHIFT 4 /* Up to 16 types */
+
+#define CTL_U32 1 /* Single u32 */
+#define CTL_U64 2 /* Single u64 */
+#define __CTL_U32A 3 /* Array of u32 */
+#define __CTL_U64A 4 /* Array of u64 */
+#define __CTL_STR 5 /* String */
+
+#define CTL_U32A(n) (__CTL_U32A | ((n) << CTL_SHIFT))
+#define CTL_U64A(n) (__CTL_U64A | ((n) << CTL_SHIFT))
+#define CTL_STR(len) (__CTL_STR | ((len) << CTL_SHIFT))
+
+#define CTL_LEN(t) ((t) >> CTL_SHIFT)
+#define CTL_TYPE(t) ((t) & ((1 << CTL_SHIFT) - 1))
+
+#endif /* CR_SYSCTL_H_ */
diff --git a/ipc_ns.c b/ipc_ns.c
index 88c6b06..a54d6ec 100644
--- a/ipc_ns.c
+++ b/ipc_ns.c
@@ -6,10 +6,12 @@
#include <sys/msg.h>
#include <sys/sem.h>
#include <sys/shm.h>
+
#include "util.h"
#include "crtools.h"
#include "syscall.h"
#include "namespaces.h"
+#include "sysctl.h"
struct ipc_ns_data {
struct ipc_ns_entry entry;
@@ -19,6 +21,27 @@ struct ipc_ns_data {
#define IPC_MSG_IDS 1
#define IPC_SHM_IDS 2
+static int ipc_sysctl_req(struct ipc_ns_entry *e, int op)
+{
+ struct sysctl_req req[] = {
+ { "kernel/sem", e->sem_ctls, CTL_U32A(4) },
+ { "kernel/msgmax", &e->msg_ctlmax, CTL_U32 },
+ { "kernel/msgmnb", &e->msg_ctlmnb, CTL_U32 },
+ { "kernel/msgmni", &e->msg_ctlmni, CTL_U32 },
+ { "kernel/auto_msgmni", &e->auto_msgmni, CTL_U32 },
+ { "kernel/shmmax", &e->shm_ctlmax, CTL_U64 },
+ { "kernel/shmall", &e->shm_ctlall, CTL_U64 },
+ { "kernel/shmmni", &e->shm_ctlmni, CTL_U32 },
+ { "kernel/shm_rmid_forced", &e->shm_rmid_forced, CTL_U32 },
+ { "fs/mqueue/queues_max", &e->mq_queues_max, CTL_U32 },
+ { "fs/mqueue/msg_max", &e->mq_msg_max, CTL_U32 },
+ { "fs/mqueue/msgsize_max", &e->mq_msgsize_max, CTL_U32 },
+ { },
+ };
+
+ return sysctl_op(req, op);
+}
+
static int collect_ipc_msg(void *data)
{
struct msginfo info;
@@ -74,149 +97,9 @@ static int collect_ipc_shm(void *data)
return 0;
}
-#ifdef CONFIG_X86_64
-static int read_ipc_sysctl_long(char *name, u64 *data, size_t size)
-{
- int fd;
- int ret;
- char buf[32];
-
- fd = open(name, O_RDONLY);
- if (fd < 0) {
- pr_perror("Can't open %s", name);
- return fd;
- }
- ret = read(fd, buf, sizeof(buf));
- if (ret < 0) {
- pr_perror("Can't read %s", name);
- ret = -errno;
- goto err;
- }
- *data = strtoull(buf, NULL, 10);
-err:
- close(fd);
- return ret;
-}
-#endif
-
-static int read_ipc_sysctl(char *name, u32 *data, size_t size)
-{
- int fd;
- int ret;
- char buf[32];
-
- fd = open(name, O_RDONLY);
- if (fd < 0) {
- pr_perror("Can't open %s", name);
- return fd;
- }
- ret = read(fd, buf, sizeof(buf));
- if (ret < 0) {
- pr_perror("Can't read %s", name);
- ret = -errno;
- goto err;
- }
- *data = (u32)strtoul(buf, NULL, 10);
-err:
- close(fd);
- return ret;
-}
-
-static int read_ipc_sem(u32 sem[])
+static int collect_ipc_tun(struct ipc_ns_entry *e)
{
- int fd;
- int ret;
- char buf[128], *ptr = buf;
- char *name = "/proc/sys/kernel/sem";
- int i;
-
- fd = open(name, O_RDONLY);
- if (fd < 0) {
- pr_perror("Can't open %s", name);
- return fd;
- }
- ret = read(fd, buf, sizeof(buf));
- if (ret < 0) {
- pr_perror("Can't read %s", name);
- ret = -errno;
- goto err;
- }
- sem[0] = (u32)strtoul(ptr, &ptr, 10); ptr++;
- sem[1] = (u32)strtoul(ptr, &ptr, 10); ptr++;
- sem[2] = (u32)strtoul(ptr, &ptr, 10); ptr++;
- sem[3] = (u32)strtoul(ptr, &ptr, 10); ptr++;
-err:
- close(fd);
- return ret;
-}
-
-static int collect_ipc_tun(struct ipc_ns_entry *entry)
-{
- int ret;
-
- ret = read_ipc_sem(entry->sem_ctls);
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/kernel/msgmax",
- &entry->msg_ctlmax, sizeof(entry->msg_ctlmax));
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/kernel/msgmnb",
- &entry->msg_ctlmnb, sizeof(entry->msg_ctlmnb));
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/kernel/msgmni",
- &entry->msg_ctlmni, sizeof(entry->msg_ctlmni));
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/kernel/auto_msgmni",
- &entry->auto_msgmni, sizeof(entry->auto_msgmni));
- if (ret < 0)
- goto err;
-#ifdef CONFIG_X86_64
- ret = read_ipc_sysctl_long("/proc/sys/kernel/shmmax",
- (u64 *)entry->shm_ctlmax, sizeof(entry->shm_ctlmax));
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl_long("/proc/sys/kernel/shmall",
- (u64 *)entry->shm_ctlall, sizeof(entry->shm_ctlall));
-#else
- ret = read_ipc_sysctl("/proc/sys/kernel/shmmax",
- entry->shm_ctlmax, sizeof(entry->shm_ctlmax));
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/kernel/shmall",
- entry->shm_ctlall, sizeof(entry->shm_ctlall));
-#endif
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/kernel/shmmni",
- &entry->shm_ctlmni, sizeof(entry->shm_ctlmni));
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/kernel/shm_rmid_forced",
- &entry->shm_rmid_forced, sizeof(entry->shm_rmid_forced));
- if (ret < 0)
- goto err;
-
-
- ret = read_ipc_sysctl("/proc/sys/fs/mqueue/queues_max",
- &entry->mq_queues_max, sizeof(entry->mq_queues_max));
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/fs/mqueue/msg_max",
- &entry->mq_msg_max, sizeof(entry->mq_msg_max));
- if (ret < 0)
- goto err;
- ret = read_ipc_sysctl("/proc/sys/fs/mqueue/msgsize_max",
- &entry->mq_msgsize_max, sizeof(entry->mq_msgsize_max));
- if (ret < 0)
- goto err;
-
- return 0;
-err:
- pr_err("Failed to dump ipc namespace tunables\n");
- return ret;
+ return ipc_sysctl_req(e, CTL_READ);
}
static int collect_ipc_data(int ns_pid, struct ipc_ns_data *ipc)
@@ -277,20 +160,7 @@ int dump_ipc_ns(int ns_pid, struct cr_fdset *fdset)
static void show_ipc_entry(struct ipc_ns_entry *entry)
{
- pr_info("/proc/sys/kernel/sem : %d\t%d\t%d\t%d\n",
- entry->sem_ctls[0], entry->sem_ctls[1],
- entry->sem_ctls[2], entry->sem_ctls[3]);
- pr_info("/proc/sys/kernel/msgmax : %d\n", entry->msg_ctlmax);
- pr_info("/proc/sys/kernel/msgmnb : %d\n", entry->msg_ctlmnb);
- pr_info("/proc/sys/kernel/msgmni : %d\n", entry->msg_ctlmni);
- pr_info("/proc/sys/kernel/auto_msgmni : %d\n", entry->auto_msgmni);
- pr_info("/proc/sys/kernel/shmmax : %ld\n", *(u64 *)entry->shm_ctlmax);
- pr_info("/proc/sys/kernel/shmall : %ld\n", *(u64 *)entry->shm_ctlall);
- pr_info("/proc/sys/kernel/shmmni : %d\n", entry->shm_ctlmni);
- pr_info("/proc/sys/kernel/shm_rmid_forced : %d\n", entry->shm_rmid_forced);
- pr_info("/proc/sys/fs/mqueue/queues_max : %d\n", entry->mq_queues_max);
- pr_info("/proc/sys/fs/mqueue/msg_max : %d\n", entry->mq_msg_max);
- pr_info("/proc/sys/fs/mqueue/msgsize_max : %d\n", entry->mq_msgsize_max);
+ ipc_sysctl_req(entry, CTL_PRINT);
}
static void show_ipc_data(int fd)
@@ -311,126 +181,9 @@ void show_ipc_ns(int fd)
pr_img_tail(CR_FD_IPCNS);
}
-#ifdef CONFIG_X86_64
-static int write_ipc_sysctl_long(char *name, u64 *data)
-{
- int fd;
- int ret;
- char buf[32];
-
- fd = open(name, O_WRONLY);
- if (fd < 0) {
- pr_perror("Can't open %s", name);
- return fd;
- }
- sprintf(buf, "%ld\n", *(long *)data);
- ret = write(fd, buf, 32);
- if (ret < 0) {
- pr_perror("Can't write %s", name);
- ret = -errno;
- }
- close(fd);
- return ret;
-}
-#endif
-
-static int write_ipc_sysctl(char *name, u32 *data)
-{
- int fd;
- int ret;
- char buf[32];
-
- fd = open(name, O_WRONLY);
- if (fd < 0) {
- pr_perror("Can't open %s", name);
- return fd;
- }
- sprintf(buf, "%d\n", *(int *)data);
- ret = write(fd, buf, 32);
- if (ret < 0) {
- pr_perror("Can't write %s", name);
- ret = -errno;
- }
- close(fd);
- return ret;
-}
-
-static int write_ipc_sem(u32 sem[])
+static int prepare_ipc_tun(struct ipc_ns_entry *e)
{
- int fd;
- int ret;
- char buf[128];
- char *name = "/proc/sys/kernel/sem";
-
- fd = open(name, O_WRONLY);
- if (fd < 0) {
- pr_perror("Can't open %s", name);
- return fd;
- }
- sprintf(buf, "%d %d %d %d\n", sem[0], sem[1], sem[2], sem[3]);
- ret = write(fd, buf, 128);
- if (ret < 0) {
- pr_perror("Can't write %s", name);
- ret = -errno;
- }
- close(fd);
- return ret;
-}
-
-static int prepare_ipc_tun(struct ipc_ns_entry *entry)
-{
- int ret;
-
- ret = write_ipc_sem(entry->sem_ctls);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/kernel/msgmax", &entry->msg_ctlmax);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/kernel/msgmnb", &entry->msg_ctlmnb);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/kernel/msgmni", &entry->msg_ctlmni);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/kernel/auto_msgmni", &entry->auto_msgmni);
- if (ret < 0)
- goto err;
-#ifdef CONFIG_X86_64
- ret = write_ipc_sysctl_long("/proc/sys/kernel/shmmax", (u64 *)entry->shm_ctlmax);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl_long("/proc/sys/kernel/shmall", (u64 *)entry->shm_ctlall);
-#else
- ret = write_ipc_sysctl("/proc/sys/kernel/shmmax", entry->shm_ctlmax);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/kernel/shmall", entry->shm_ctlall);
-#endif
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/kernel/shmmni", &entry->shm_ctlmni);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/kernel/shm_rmid_forced", &entry->shm_rmid_forced);
- if (ret < 0)
- goto err;
-
-
- ret = write_ipc_sysctl("/proc/sys/fs/mqueue/queues_max", &entry->mq_queues_max);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/fs/mqueue/msg_max", &entry->mq_msg_max);
- if (ret < 0)
- goto err;
- ret = write_ipc_sysctl("/proc/sys/fs/mqueue/msgsize_max", &entry->mq_msgsize_max);
- if (ret < 0)
- goto err;
-
- return 0;
-err:
- pr_err("Failed to restore ipc namespace tunables\n");
- return ret;
+ return ipc_sysctl_req(e, CTL_WRITE);
}
static int prepare_ipc_data(int fd)
diff --git a/sysctl.c b/sysctl.c
new file mode 100644
index 0000000..6d0f8bd
--- /dev/null
+++ b/sysctl.c
@@ -0,0 +1,216 @@
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+
+#include "types.h"
+#include "sysctl.h"
+#include "util.h"
+
+#define __SYSCTL_OP(__ret, __fd, __req, __type, __nr, __op) \
+do { \
+ if (__op == CTL_READ) \
+ __ret = sysctl_read_##__type(__fd, __req, \
+ (__type *)(__req)->arg, \
+ __nr); \
+ else if (__op == CTL_WRITE) \
+ __ret = sysctl_write_##__type(__fd, __req, \
+ (__type *)(__req)->arg, \
+ __nr); \
+ else if (__op == CTL_PRINT) \
+ __ret = sysctl_print_##__type(__fd, __req, \
+ (__type *)(__req)->arg, \
+ __nr); \
+ else \
+ __ret = -1; \
+} while (0)
+
+#define GEN_SYSCTL_READ_FUNC(__type, __conv) \
+static int sysctl_read_##__type(int fd, \
+ struct sysctl_req *req, \
+ __type *arg, \
+ int nr) \
+{ \
+ char buf[1024] = {0}; \
+ int i, ret = -1; \
+ char *p = buf; \
+ \
+ ret = read(fd, buf, sizeof(buf)); \
+ if (ret < 0) { \
+ pr_perror("Can't read %s", req->name); \
+ ret = -1; \
+ goto err; \
+ } \
+ \
+ for (i = 0; i < nr && p < buf + sizeof(buf); p++, i++) \
+ ((__type *)arg)[i] = __conv(p, &p, 10); \
+ \
+ if (i != nr) { \
+ pr_err("Not enough params for %s (%d != %d)\n", \
+ req->name, i, nr); \
+ goto err; \
+ } \
+ \
+ ret = 0; \
+ \
+err: \
+ return ret; \
+}
+
+#define GEN_SYSCTL_WRITE_FUNC(__type, __fmt) \
+static int sysctl_write_##__type(int fd, \
+ struct sysctl_req *req, \
+ __type *arg, \
+ int nr) \
+{ \
+ char buf[1024]; \
+ int i, ret = -1; \
+ int off = 0; \
+ \
+ for (i = 0; i < nr && off < sizeof(buf) - 2; i++) { \
+ snprintf(&buf[off], sizeof(buf) - off, __fmt, arg[i]); \
+ off += strlen(&buf[off]); \
+ } \
+ \
+ if (i != nr) { \
+ pr_err("Not enough space for %s (%d != %d)\n", \
+ req->name, i, nr); \
+ goto err; \
+ } \
+ \
+ /* trailing spaces in format */ \
+ while (off > 0 && isspace(buf[off - 1])) \
+ off--; \
+ buf[off + 0] = '\n'; \
+ buf[off + 1] = '\0'; \
+ ret = write(fd, buf, off + 2); \
+ if (ret < 0) { \
+ pr_perror("Can't write %s", req->name); \
+ ret = -1; \
+ goto err; \
+ } \
+ \
+ ret = 0; \
+err: \
+ return ret; \
+}
+
+#define GEN_SYSCTL_PRINT_FUNC(__type, __fmt) \
+static int sysctl_print_##__type(int fd, \
+ struct sysctl_req *req, \
+ __type *arg, \
+ int nr) \
+{ \
+ int i; \
+ pr_info("sysctl: <%s> = <", req->name); \
+ for (i = 0; i < nr; i++) \
+ pr_info(__fmt, arg[i]); \
+ pr_info(">\n"); \
+ \
+ return 0; \
+}
+
+GEN_SYSCTL_READ_FUNC(u32, strtoul);
+GEN_SYSCTL_READ_FUNC(u64, strtoull);
+
+GEN_SYSCTL_WRITE_FUNC(u32, "%u ");
+GEN_SYSCTL_WRITE_FUNC(u64, "%lu ");
+
+GEN_SYSCTL_PRINT_FUNC(u32, "%u ");
+GEN_SYSCTL_PRINT_FUNC(u64, "%lu ");
+GEN_SYSCTL_PRINT_FUNC(char, "%c");
+
+static int
+sysctl_write_char(int fd, struct sysctl_req *req, char *arg, int nr)
+{
+ pr_debug("%s nr %d\n", req->name, nr);
+ if (dprintf(fd, "%s\n", arg) < 0)
+ return -1;
+
+ return 0;
+}
+
+static int
+sysctl_read_char(int fd, struct sysctl_req *req, char *arg, int nr)
+{
+ int ret = -1;
+
+ pr_debug("%s nr %d\n", req->name, nr);
+ ret = read(fd, arg, nr);
+ if (ret < 0) {
+ pr_perror("Can't read %s", req->name);
+ goto err;
+ }
+ ret = 0;
+
+err:
+ return ret;
+}
+
+static int __sysctl_op(int dir, struct sysctl_req *req, int op)
+{
+ int fd = -1;
+ int ret = -1;
+ int nr = 1;
+
+ if (dir > 0) {
+ int flags;
+
+ if (op == CTL_READ)
+ flags = O_RDONLY;
+ else
+ flags = O_WRONLY;
+
+ fd = openat(dir, req->name, flags);
+ if (fd < 0) {
+ pr_perror("Can't open sysctl %s", req->name);
+ return -1;
+ }
+ }
+
+ switch (CTL_TYPE(req->type)) {
+ case __CTL_U32A:
+ nr = CTL_LEN(req->type);
+ case CTL_U32:
+ __SYSCTL_OP(ret, fd, req, u32, nr, op);
+ break;
+ case __CTL_U64A:
+ nr = CTL_LEN(req->type);
+ case CTL_U64:
+ __SYSCTL_OP(ret, fd, req, u64, nr, op);
+ break;
+ case __CTL_STR:
+ nr = CTL_LEN(req->type);
+ __SYSCTL_OP(ret, fd, req, char, nr, op);
+ break;
+ }
+
+ if (fd > 0)
+ close(fd);
+
+ return ret;
+}
+
+int sysctl_op(struct sysctl_req *req, int op)
+{
+ int ret = 0;
+ int dir = -1;
+
+ if (op != CTL_PRINT) {
+ dir = open("/proc/sys", O_RDONLY);
+ if (dir < 0) {
+ pr_perror("Can't open sysctl dir");
+ return -1;
+ }
+ }
+
+ while (req->name) {
+ ret = __sysctl_op(dir, req, op);
+ if (ret < 0)
+ break;
+ req++;
+ }
+
+ if (dir > 0)
+ close(dir);
+ return ret;
+}
diff --git a/uts_ns.c b/uts_ns.c
index 306aca3..32f9d25 100644
--- a/uts_ns.c
+++ b/uts_ns.c
@@ -6,6 +6,7 @@
#include "crtools.h"
#include "syscall.h"
#include "namespaces.h"
+#include "sysctl.h"
static int dump_uts_string(int fd, char *str)
{
@@ -44,62 +45,55 @@ int dump_uts_ns(int ns_pid, struct cr_fdset *fdset)
return ret;
}
-static int prepare_uts_str(int fd, char *n)
+static int read_uts_str(int fd, char *n, int size)
{
int ret;
u32 len;
- char str[65], path[128];
ret = read_img(fd, &len);
- if (ret > 0) {
- if (len >= sizeof(str)) {
- pr_err("Corrupted %s\n", n);
- return -1;
- }
-
- ret = read_img_buf(fd, str, len);
- if (ret < 0)
- return -1;
-
- str[len] = '\0';
-
- snprintf(path, sizeof(path),
- "/proc/sys/kernel/%s", n);
- fd = open(path, O_WRONLY);
- if (fd < 0) {
- pr_perror("Can't open %s", path);
- return -1;
- }
-
- pr_info("Restoring %s to [%s]\n", n, str);
-
- ret = write(fd, str, len);
- close(fd);
- if (ret != len) {
- pr_perror("Can't write %s to %s",
- str, path);
- return -1;
- }
+ if (ret < 0)
+ return -1;
- ret = 0;
+ if (len >= size) {
+ pr_err("Corrupted %s\n", n);
+ return -1;
}
- return ret;
+ ret = read_img_buf(fd, n, len);
+ if (ret < 0)
+ return -1;
+
+ n[len] = '\0';
+ return 0;
}
int prepare_utsns(int pid)
{
int fd, ret;
u32 len;
+ char hostname[65];
+ char domainname[65];
+
+ struct sysctl_req req[] = {
+ { "kernel/hostname", hostname, CTL_STR(sizeof(hostname)) },
+ { "kernel/domainname", domainname, CTL_STR(sizeof(hostname)) },
+ { },
+ };
fd = open_image_ro(CR_FD_UTSNS, pid);
if (fd < 0)
return -1;
- ret = prepare_uts_str(fd, "hostname");
- if (!ret)
- ret = prepare_uts_str(fd, "domainname");
+ ret = read_uts_str(fd, hostname, sizeof(hostname));
+ if (ret < 0)
+ goto out;
+
+ ret = read_uts_str(fd, domainname, sizeof(domainname));
+ if (ret < 0)
+ goto out;
+ ret = sysctl_op(req, CTL_WRITE);
+out:
close(fd);
return ret;
}
--
1.7.7.6
More information about the CRIU
mailing list