From: Masatake YAMATO Date: Wed, 1 May 2024 02:46:05 +0000 (+0900) Subject: lsns: (refactor) add get_{parent|owner}_ns_ino() implementing some parts of get_ns_ino() X-Git-Tag: v2.42-start~354^2~7 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=cc8174cf1e6c2077818ee9cdd4d8af5766dfb38d;p=thirdparty%2Futil-linux.git lsns: (refactor) add get_{parent|owner}_ns_ino() implementing some parts of get_ns_ino() get_ns_ino() returns three inode numbers. The code for the two of three, inodes for PARENT and USERNS, is moved to the new functions. So we can reuse the code in other places in lsns. Signed-off-by: Masatake YAMATO --- diff --git a/sys-utils/lsns.c b/sys-utils/lsns.c index af763eeac..5e5358a49 100644 --- a/sys-utils/lsns.c +++ b/sys-utils/lsns.c @@ -301,65 +301,106 @@ static inline const struct colinfo *get_column_info(unsigned num) return &infos[ get_column_id(num) ]; } -static int get_ns_ino(struct path_cxt *pc, const char *nsname, ino_t *ino, ino_t *pino, ino_t *oino) +#ifdef USE_NS_GET_API +/* Get the inode number for the parent namespace of the namespace `fd' specifies. + * If `pfd' is non-null, the file descriptor opening the parent namespace.*/ +static int get_parent_ns_ino(int fd, enum lsns_type lsns_type, ino_t *pino, int *pfd) { struct stat st; - char path[16]; + int my_fd; - snprintf(path, sizeof(path), "ns/%s", nsname); - - *ino = 0; - if (ul_path_stat(pc, &st, 0, path) != 0) - return -errno; - *ino = st.st_ino; + if (pfd == NULL) + pfd = &my_fd; *pino = 0; - *oino = 0; + *pfd = -1; -#ifdef USE_NS_GET_API - int fd, pfd, ofd; - fd = ul_path_open(pc, 0, path); - if (fd < 0) - return -errno; - if (strcmp(nsname, "pid") == 0 || strcmp(nsname, "user") == 0) { - if ((pfd = lsns_ioctl(fd, NS_GET_PARENT)) < 0) { + if (lsns_type == LSNS_TYPE_PID || lsns_type == LSNS_TYPE_USER) { + if ((*pfd = lsns_ioctl(fd, NS_GET_PARENT)) < 0) { if (errno == EPERM /* On the test platforms, "build (qemu-user, s390x)" and * "build (qemu-user, riscv64)", the ioctl reported ENOSYS. */ || errno == ENOSYS) - goto user; - close(fd); + return 0; return -errno; } - if (fstat(pfd, &st) < 0) { - close(pfd); - close(fd); + if (fstat(*pfd, &st) < 0) { + close(*pfd); + *pfd = -1; return -errno; } *pino = st.st_ino; - close(pfd); } - user: - if ((ofd = lsns_ioctl(fd, NS_GET_USERNS)) < 0) { + + if (pfd == &my_fd) + close(*pfd); + return 0; +} + +/* Get the inode number for the owner (user) namespace of the namespace `fd' specifies. + * If `pfd' is non-null, the file descriptor opening the user namespace.*/ +static int get_owner_ns_ino(int fd, ino_t *oino, int *ofd) +{ + struct stat st; + int my_fd; + + if (ofd == NULL) + ofd = &my_fd; + + *oino = 0; + *ofd = -1; + + if ((*ofd = lsns_ioctl(fd, NS_GET_USERNS)) < 0) { if (errno == EPERM /* On the test platforms, "build (qemu-user, s390x)" and * "build (qemu-user, riscv64)", the ioctl reported ENOSYS. */ || errno == ENOSYS) - goto out; - close(fd); + return 0; return -errno; } - if (fstat(ofd, &st) < 0) { - close(ofd); - close(fd); + if (fstat(*ofd, &st) < 0) { + close(*ofd); + *ofd = -1; return -errno; } *oino = st.st_ino; - close(ofd); - out: + + if (ofd == &my_fd) + close(*ofd); + return 0; +} +#endif + +static int get_ns_ino(struct path_cxt *pc, const char *nsname, ino_t *ino, ino_t *pino, ino_t *oino) +{ + struct stat st; + char path[16]; + + snprintf(path, sizeof(path), "ns/%s", nsname); + + *ino = 0; + if (ul_path_stat(pc, &st, 0, path) != 0) + return -errno; + *ino = st.st_ino; + + *pino = 0; + *oino = 0; + +#ifdef USE_NS_GET_API + int r; + enum lsns_type lsns_type; + int fd = ul_path_open(pc, 0, path); + if (fd < 0) + return -errno; + lsns_type = ns_name2type(nsname); + + r = get_parent_ns_ino(fd, lsns_type, pino, NULL); + if (r == 0) + r = get_owner_ns_ino(fd, oino, NULL); close(fd); + return r; #endif return 0; }