diff options
Diffstat (limited to 'criu/sysctl.c')
-rw-r--r-- | criu/sysctl.c | 192 |
1 files changed, 89 insertions, 103 deletions
diff --git a/criu/sysctl.c b/criu/sysctl.c index e48476560..b06688712 100644 --- a/criu/sysctl.c +++ b/criu/sysctl.c @@ -16,105 +16,92 @@ #define KNOWN_NS_MASK (CLONE_NEWUTS | CLONE_NEWNET | CLONE_NEWIPC) struct sysctl_userns_req { - int op; - unsigned int ns; - size_t nr_req; - struct sysctl_req *reqs; + int op; + unsigned int ns; + size_t nr_req; + struct sysctl_req *reqs; }; -#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 \ - __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 __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 \ + __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) - 1; 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'; \ - ret = write(fd, buf, off + 1); \ - if (ret < 0) { \ - pr_perror("Can't write %s", req->name); \ - ret = -1; \ - 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) - 1; 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'; \ + ret = write(fd, buf, off + 1); \ + if (ret < 0) { \ + pr_perror("Can't write %s", req->name); \ + ret = -1; \ + goto err; \ + } \ + \ + ret = 0; \ + err: \ + return ret; \ + } GEN_SYSCTL_READ_FUNC(u32, strtoul); GEN_SYSCTL_READ_FUNC(u64, strtoull); GEN_SYSCTL_READ_FUNC(s32, strtol); GEN_SYSCTL_WRITE_FUNC(u32, "%u "); -GEN_SYSCTL_WRITE_FUNC(u64, "%"PRIu64" "); +GEN_SYSCTL_WRITE_FUNC(u64, "%" PRIu64 " "); GEN_SYSCTL_WRITE_FUNC(s32, "%d "); -static int -sysctl_write_char(int fd, struct sysctl_req *req, char *arg, int nr) +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) @@ -123,19 +110,18 @@ sysctl_write_char(int fd, struct sysctl_req *req, char *arg, int nr) return 0; } -static int -sysctl_read_char(int fd, struct sysctl_req *req, char *arg, int nr) +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 - 1); if (ret < 0) { - if (errno != EIO || !(req->flags & CTL_FLAGS_READ_EIO_SKIP)) + if (errno != EIO || !(req->flags & CTL_FLAGS_READ_EIO_SKIP)) pr_perror("Can't read %s", req->name); goto err; } - arg[ret]='\0'; + arg[ret] = '\0'; ret = 0; err: @@ -144,7 +130,7 @@ err: static int sysctl_userns_arg_size(int type) { - switch(CTL_TYPE(type)) { + switch (CTL_TYPE(type)) { case __CTL_U32A: return sizeof(u32) * CTL_LEN(type); case CTL_U32: @@ -204,7 +190,7 @@ static int __userns_sysctl_op(void *arg, int proc_fd, pid_t pid) pid_t worker; // fix up the pointer - req = userns_req->reqs = (struct sysctl_req *) &userns_req[1]; + req = userns_req->reqs = (struct sysctl_req *)&userns_req[1]; /* For files in the IPC/UTS namespaces, restoring is more complicated * than for net. Unprivileged users cannot even open these files, so @@ -234,17 +220,17 @@ static int __userns_sysctl_op(void *arg, int proc_fd, pid_t pid) memset(fds, -1, sizeof(int) * userns_req->nr_req); - for (i = 0; i < userns_req->nr_req; i++) { + for (i = 0; i < userns_req->nr_req; i++) { int arg_len = sysctl_userns_arg_size(req->type); - int name_len = strlen((char *) &req[1]) + 1; + int name_len = strlen((char *)&req[1]) + 1; int total_len = sizeof(*req) + arg_len + name_len; int flags; /* fix up the pointers */ - req->name = (char *) &req[1]; + req->name = (char *)&req[1]; req->arg = req->name + name_len; - if (((char *) req) + total_len >= ((char *) userns_req) + MAX_UNSFD_MSG_SIZE) { + if (((char *)req) + total_len >= ((char *)userns_req) + MAX_UNSFD_MSG_SIZE) { pr_err("bad sysctl req %s, too big: %d\n", req->name, total_len); goto out; } @@ -268,7 +254,7 @@ static int __userns_sysctl_op(void *arg, int proc_fd, pid_t pid) reqs[i] = req; fds[i] = fd; - req = (struct sysctl_req *) (((char *) req) + total_len); + req = (struct sysctl_req *)(((char *)req) + total_len); } /* @@ -436,7 +422,7 @@ int sysctl_op(struct sysctl_req *req, size_t nr_req, int op, unsigned int ns) userns_req->op = op; userns_req->nr_req = nr_req; userns_req->ns = ns; - userns_req->reqs = (struct sysctl_req *) (&userns_req[1]); + userns_req->reqs = (struct sysctl_req *)(&userns_req[1]); cur = userns_req->reqs; for (i = 0; i < nr_req; i++) { @@ -444,7 +430,7 @@ int sysctl_op(struct sysctl_req *req, size_t nr_req, int op, unsigned int ns) int name_len = strlen(req[i].name) + 1; int total_len = sizeof(*cur) + arg_len + name_len; - if (((char *) cur) + total_len >= ((char *) userns_req) + MAX_UNSFD_MSG_SIZE) { + if (((char *)cur) + total_len >= ((char *)userns_req) + MAX_UNSFD_MSG_SIZE) { pr_err("sysctl msg %s too big: %d\n", req[i].name, total_len); return -1; } @@ -453,13 +439,13 @@ int sysctl_op(struct sysctl_req *req, size_t nr_req, int op, unsigned int ns) cur->type = req[i].type; cur->flags = req[i].flags; - cur->name = (char *) &cur[1]; + cur->name = (char *)&cur[1]; strcpy(cur->name, req[i].name); cur->arg = cur->name + name_len; memcpy(cur->arg, req[i].arg, arg_len); - cur = (struct sysctl_req *) (((char *) cur) + total_len); + cur = (struct sysctl_req *)(((char *)cur) + total_len); } fd = open_proc(PROC_SELF, "ns"); |