]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
lsns: report unsupported ioctl
authorThomas Weißschuh <thomas@t-8ch.de>
Thu, 15 Dec 2022 16:26:51 +0000 (16:26 +0000)
committerThomas Weißschuh <thomas@t-8ch.de>
Wed, 21 Dec 2022 03:41:27 +0000 (03:41 +0000)
sys-utils/lsns.8.adoc
sys-utils/lsns.c
tests/ts/lsns/ioctl_ns

index 0e57ba84770357441014b254c28e2ebbbea0256f..ea6c87e9d1a21033b2443bb48c96af835eae20b4 100644 (file)
@@ -72,6 +72,17 @@ Use tree-like output format. If *process* is given as _rel_, print process tree(
 
 include::man-common/help-version.adoc[]
 
+== EXIT STATUS
+
+The *lsns* utility exits with one of the following values:
+
+*0*::
+Success.
+*1*::
+General error.
+*2*::
+An ioctl was unknown to the kernel.
+
 == AUTHORS
 
 mailto:kzak@redhat.com[Karel Zak]
index 81adc25a4bffc4e6c0f275c1843d8c52be976231..5b909d4b79cfd392f31fe1a4eed29732f3a9335a 100644 (file)
@@ -73,9 +73,17 @@ UL_DEBUG_DEFINE_MASKNAMES(lsns) = UL_DEBUG_EMPTY_MASKNAMES;
 #define DBG(m, x)       __UL_DBG(lsns, LSNS_DEBUG_, m, x)
 #define ON_DBG(m, x)    __UL_DBG_CALL(lsns, LSNS_DEBUG_, m, x)
 
+#define lsns_ioctl(fildes, request, ...) __extension__ ({ \
+       int ret = ioctl(fildes, request, ##__VA_ARGS__); \
+       if (ret == -1 && errno == ENOTTY) \
+               warnx("Unsupported ioctl %s", #request); \
+       ret; })
+
 #define UL_DEBUG_CURRENT_MASK  UL_DEBUG_MASK(lsns)
 #include "debugobj.h"
 
+#define EXIT_UNSUPPORTED_IOCTL 2
+
 static struct idcache *uid_cache = NULL;
 
 /* column IDs */
@@ -306,7 +314,7 @@ static int get_ns_ino(int dir, const char *nsname, ino_t *ino, ino_t *pino, ino_
        if (fd < 0)
                return -errno;
        if (strcmp(nsname, "pid") == 0 || strcmp(nsname, "user") == 0) {
-               if ((pfd = ioctl(fd, NS_GET_PARENT)) < 0) {
+               if ((pfd = lsns_ioctl(fd, NS_GET_PARENT)) < 0) {
                        if (errno == EPERM)
                                goto user;
                        close(fd);
@@ -321,7 +329,7 @@ static int get_ns_ino(int dir, const char *nsname, ino_t *ino, ino_t *pino, ino_
                close(pfd);
        }
  user:
-       if ((ofd = ioctl(fd, NS_GET_USERNS)) < 0) {
+       if ((ofd = lsns_ioctl(fd, NS_GET_USERNS)) < 0) {
                if (errno == EPERM)
                        goto out;
                close(fd);
@@ -723,14 +731,14 @@ static struct lsns_namespace *add_namespace_for_nsfd(struct lsns *ls, int fd, in
        struct lsns_namespace *ns;
        int clone_type, lsns_type;
 
-       clone_type = ioctl(fd, NS_GET_NSTYPE);
+       clone_type = lsns_ioctl(fd, NS_GET_NSTYPE);
        if (clone_type < 0)
                return NULL;
        lsns_type = clone_type_to_lsns_type(clone_type);
        if (lsns_type < 0 || ls->fltr_types[lsns_type] == 0)
                return NULL;
 
-       fd_owner = ioctl(fd, NS_GET_USERNS);
+       fd_owner = lsns_ioctl(fd, NS_GET_USERNS);
        if (fd_owner < 0)
                goto parent;
        if (fstat(fd_owner, &st_owner) < 0)
@@ -738,7 +746,7 @@ static struct lsns_namespace *add_namespace_for_nsfd(struct lsns *ls, int fd, in
        ino_owner = st_owner.st_ino;
 
  parent:
-       fd_parent = ioctl(fd, NS_GET_PARENT);
+       fd_parent = lsns_ioctl(fd, NS_GET_PARENT);
        if (fd_parent < 0)
                goto add_ns;
        if (fstat(fd_parent, &st_parent) < 0)
@@ -747,7 +755,7 @@ static struct lsns_namespace *add_namespace_for_nsfd(struct lsns *ls, int fd, in
 
  add_ns:
        ns = add_namespace(ls, lsns_type, ino, ino_parent, ino_owner);
-       ioctl(fd, NS_GET_OWNER_UID, &ns->uid_fallback);
+       lsns_ioctl(fd, NS_GET_OWNER_UID, &ns->uid_fallback);
        add_uid(uid_cache, ns->uid_fallback);
 
        if ((lsns_type == LSNS_ID_USER || lsns_type == LSNS_ID_PID)
@@ -793,7 +801,7 @@ static void interpolate_missing_namespaces(struct lsns *ls, struct lsns_namespac
        if (fd_orphan < 0)
                return;
 
-       fd_missing = ioctl(fd_orphan, cmd[rela]);
+       fd_missing = lsns_ioctl(fd_orphan, cmd[rela]);
        close(fd_orphan);
        if (fd_missing < 0)
                return;
@@ -1506,5 +1514,9 @@ int main(int argc, char *argv[])
 
        free_all(&ls);
 
-       return r == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
+       switch (r) {
+               case 0: return EXIT_SUCCESS;
+               case -ENOTTY: return EXIT_UNSUPPORTED_IOCTL;
+               default: return EXIT_FAILURE;
+       }
 }
index 3385795198b2447ff0a96889926bfcda7c29518e..7fc998bc067f7cf341f958fa2c291fc888b92190 100755 (executable)
@@ -34,6 +34,11 @@ ts_check_prog "mkfifo"
 ts_check_prog "touch"
 ts_check_prog "uniq"
 
+"$TS_CMD_LSNS" > /dev/null 2>&1
+if [ $? -eq 2 ]; then
+       ts_skip "ioctl not supported"
+fi
+
 # 32bit userspace (NS ioctls) does not work as expected with 64bit kernel
 WORDSIZE=$($TS_HELPER_SYSINFO WORDSIZE)
 if [ $WORDSIZE -eq 32 ]; then