]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
Merge branch 'lsfd--fix-2691' of https://github.com/masatake/util-linux
authorKarel Zak <kzak@redhat.com>
Tue, 23 Jan 2024 10:07:58 +0000 (11:07 +0100)
committerKarel Zak <kzak@redhat.com>
Tue, 23 Jan 2024 10:07:58 +0000 (11:07 +0100)
* 'lsfd--fix-2691' of https://github.com/masatake/util-linux:
  tests: (lsfd::column-xmode) skip some subtests if OFD locks are not available
  tests: (lsfd) skip mkfds-netns if SIOCGSKNS is not defined
  tests: (lsfd) add lsfd_check_mkfds_factory as a help function
  tests: (test_mkfds) add --is-available option
  lsfd: build lsfd even if kcmp.h is not available
  tests: (refactor (test_mkfds, lsfd)) use TS_EXIT_NOTSUPP instead of EXIT_ENOSYS

1  2 
misc-utils/lsfd.c
tests/helpers/test_mkfds.c

diff --combined misc-utils/lsfd.c
index 8589d9397c6d377dcf89bbe3759c0aad407be519,2c1a880c4ea979dfb73ecbae378dec9a1a576b11..51d7911144c3a4dd7e7135a616f1eb62b7c7be45
  #include <sys/uio.h>
  #include <linux/sched.h>
  #include <sys/syscall.h>
- #include <linux/kcmp.h>
+ #ifdef HAVE_LINUX_KCMP_H
+ #  include <linux/kcmp.h>
  static int kcmp(pid_t pid1, pid_t pid2, int type,
                unsigned long idx1, unsigned long idx2)
  {
        return syscall(SYS_kcmp, pid1, pid2, type, idx1, idx2);
  }
+ #else
+ #  ifndef KCMP_FS
+ #    define KCMP_FS 0
+ #  endif
+ #  ifndef KCMP_VM
+ #    define KCMP_VM 0
+ #  endif
+ #  ifndef KCMP_FILES
+ #    define KCMP_FILES 0
+ #  endif
+ static int kcmp(pid_t pid1 __attribute__((__unused__)),
+               pid_t pid2 __attribute__((__unused__)),
+               int type __attribute__((__unused__)),
+               unsigned long idx1 __attribute__((__unused__)),
+               unsigned long idx2 __attribute__((__unused__)))
+ {
+       /* lsfd uses kcmp only for optimization. If the platform doesn't provide
+        * kcmp, just returning an error is acceptable. */
+       errno = ENOSYS;
+       return -1;
+ }
+ #endif
  
  /* See proc(5).
   * Defined in linux/include/linux/sched.h private header file. */
@@@ -1530,7 -1554,7 +1554,7 @@@ static void mark_poll_fds_as_multiplexe
        }
  
   out:
 -      free (local.iov_base);
 +      free(local.iov_base);
  }
  
  static void mark_select_fds_as_multiplexed(char *buf,
index 3eb627734ae40705f445bee9521b34f9d0e5e47a,9e8e883dbe2fdcc716d7e26452242296e6da7b28..642f8ec9a6dee77ce8a701a6478c953f76767d1f
@@@ -20,6 -20,7 +20,7 @@@
  #include "c.h"
  #include "xalloc.h"
  #include "test_mkfds.h"
+ #include "exitcodes.h"
  
  #include <arpa/inet.h>
  #include <ctype.h>
@@@ -64,7 -65,6 +65,6 @@@
  #include <time.h>
  #include <unistd.h>
  
- #define EXIT_ENOSYS 17
  #define EXIT_EPERM  18
  #define EXIT_ENOPROTOOPT 19
  #define EXIT_EPROTONOSUPPORT 20
@@@ -81,6 -81,7 +81,7 @@@ static void __attribute__((__noreturn__
        fprintf(out, " %s [options] FACTORY FD... [PARAM=VAL...]\n", program_invocation_short_name);
  
        fputs("\nOptions:\n", out);
+       fputs(" -a, --is-available <factory>  exit 0 if the factory is available\n", out);
        fputs(" -l, --list                    list available file descriptor factories and exit\n", out);
        fputs(" -I, --parameters <factory>    list parameters the factory takes\n", out);
        fputs(" -r, --comm <name>             rename self\n", out);
@@@ -306,7 -307,7 +307,7 @@@ static struct arg decode_arg(const cha
                                v = NULL;
                }
        }
 -      arg.v = ptype_classes [p->type].read (v, &p->defv);
 +      arg.v = ptype_classes [p->type].read(v, &p->defv);
        arg.free = ptype_classes [p->type].free;
        return arg;
  }
@@@ -507,6 -508,7 +508,7 @@@ static void lock_fn_posix_rw(int fd, co
        }
  }
  
+ #ifdef F_OFD_SETLK
  static void lock_fn_ofd_r_(int fd, const char *fname, int dupfd)
  {
        struct flock r = {
@@@ -582,6 -584,7 +584,7 @@@ static void lock_fn_ofd_rw(int fd, cons
                err(EXIT_FAILURE, "failed to lock(write)");
        }
  }
+ #endif        /* F_OFD_SETLK */
  
  static void lock_fn_lease_w(int fd, const char *fname, int dupfd)
  {
@@@ -646,6 -649,7 +649,7 @@@ static void *make_w_regular_file(const 
                if (iWrite_bytes < 3)
                        iWrite_bytes = 3;
                lock_fn = lock_fn_posix_rw;
+ #ifdef F_OFD_SETLK
        } else if (strcmp(sLock, "ofd-r-") == 0) {
                bReadable = true;
                if (iWrite_bytes < 1)
                if (iWrite_bytes < 3)
                        iWrite_bytes = 3;
                lock_fn = lock_fn_ofd_rw;
+ #else
+       } else if (strcmp(sLock, "ofd-r-") == 0
+             || strcmp(sLock, "ofd--w") == 0
+             || strcmp(sLock, "ofd-rw") == 0) {
+               errx(EXIT_ENOSYS, "no availability for ofd lock");
+ #endif        /* F_OFD_SETLK */
        } else if (strcmp(sLock, "lease-w") == 0)
                lock_fn = lock_fn_lease_w;
        else
                        int e = errno;
                        close(fd);
                        unlink(fname);
 -                      free (fname);
 +                      free(fname);
                        errno = e;
                        err(EXIT_FAILURE, "failed to dup %d -> %d", fd, fdescs[0].fd);
                }
                        errno = e;
                        err(EXIT_FAILURE, "failed in dup2");
                }
 -              data = xmalloc(sizeof (iDupfd));
 +              data = xmalloc(sizeof(iDupfd));
                *((int *)data) = iDupfd;
        }
  
@@@ -740,7 -750,7 +750,7 @@@ static void free_after_closing_duplicat
        if (data) {
                int *fdp = data;
                close(*fdp);
 -              free (data);
 +              free(data);
        }
  }
  
@@@ -1131,7 -1141,7 +1141,7 @@@ static void *make_mmapped_packet_socket
                    "failed to specify a buffer spec to a packet socket");
        }
  
 -      munmap_data = xmalloc(sizeof (*munmap_data));
 +      munmap_data = xmalloc(sizeof(*munmap_data));
        munmap_data->len = (size_t) req.tp_block_size * req.tp_block_nr;
        munmap_data->ptr = mmap(NULL, munmap_data->len, PROT_WRITE, MAP_SHARED, sd, 0);
        if (munmap_data->ptr == MAP_FAILED) {
@@@ -1171,8 -1181,7 +1181,7 @@@ static void *make_pidfd(const struct fa
  
        int fd = pidfd_open(pid, 0);
        if (fd < 0)
-               err((errno == ENOSYS? EXIT_ENOSYS: EXIT_FAILURE),
-                   "failed in pidfd_open(%d)", (int)pid);
+               err_nosys(EXIT_FAILURE, "failed in pidfd_open(%d)", (int)pid);
        free_arg(&target_pid);
  
        if (fd != fdescs[0].fd) {
@@@ -2226,6 -2235,7 +2235,7 @@@ static void *make_ping6(const struct fa
                                (struct sockaddr *)&in6);
  }
  
+ #ifdef SIOCGSKNS
  static void *make_netns(const struct factory *factory _U_, struct fdesc fdescs[],
                        int argc _U_, char ** argv _U_)
  {
  
        int ns = ioctl(sd, SIOCGSKNS);
        if (ns < 0)
-               err((errno == ENOSYS? EXIT_ENOSYS: EXIT_FAILURE),
-                   "failed in ioctl(SIOCGSKNS)");
+               err_nosys(EXIT_FAILURE, "failed in ioctl(SIOCGSKNS)");
        close(sd);
  
        if (ns != fdescs[0].fd) {
  
        return NULL;
  }
+ #endif        /* SIOCGSKNS */
  
  static void *make_netlink(const struct factory *factory, struct fdesc fdescs[],
                          int argc, char ** argv)
@@@ -2708,9 -2718,9 +2718,9 @@@ static void *make_eventpoll(const struc
                        for (size_t j = i; j > 0; j--)
                                close(fdescs[j].fd);
                        errno = e;
 -                      err (EXIT_FAILURE,
 -                           "failed to add fd %d to the eventpoll fd with epoll_ctl",
 -                           fdescs[i].fd);
 +                      err(EXIT_FAILURE,
 +                          "failed to add fd %d to the eventpoll fd with epoll_ctl",
 +                          fdescs[i].fd);
                }
        }
  
@@@ -2942,8 -2952,7 +2952,7 @@@ static void *make_bpf_prog(const struc
  
        bfd = syscall(SYS_bpf, BPF_PROG_LOAD, &attr, sizeof(attr));
        if (bfd < 0)
-               err((errno == ENOSYS? EXIT_ENOSYS: EXIT_FAILURE),
-                   "failed in bpf(BPF_PROG_LOAD)");
+               err_nosys(EXIT_FAILURE, "failed in bpf(BPF_PROG_LOAD)");
  
        if (bfd != fdescs[0].fd) {
                if (dup2(bfd, fdescs[0].fd) < 0) {
@@@ -3044,8 -3053,7 +3053,7 @@@ static void *make_bpf_map(const struct 
  
        bfd = syscall(SYS_bpf, BPF_MAP_CREATE, &attr, sizeof(attr));
        if (bfd < 0)
-               err((errno == ENOSYS? EXIT_ENOSYS: EXIT_FAILURE),
-                   "failed in bpf(BPF_MAP_CREATE)");
+               err_nosys(EXIT_FAILURE, "failed in bpf(BPF_MAP_CREATE)");
  
        if (bfd != fdescs[0].fd) {
                if (dup2(bfd, fdescs[0].fd) < 0) {
@@@ -3760,6 -3768,7 +3768,7 @@@ static const struct factory factories[
                        PARAM_END
                }
        },
+ #ifdef SIOCGSKNS
        {
                .name = "netns",
                .desc = "open a file specifying a netns",
                        PARAM_END
                }
        },
+ #endif
        {
                .name = "netlink",
                .desc = "AF_NETLINK sockets",
@@@ -4206,6 -4216,15 +4216,15 @@@ static void list_multiplexers(void
                puts(multiplexers[i].name);
  }
  
+ static bool is_available(const char *factory)
+ {
+       for (size_t i = 0; i < ARRAY_SIZE(factories); i++)
+               if (strcmp(factories[i].name, factory) == 0)
+                       return true;
+       return false;
+ }
  int main(int argc, char **argv)
  {
        int c;
        struct multiplexer *wait_event = NULL;
  
        static const struct option longopts[] = {
+               { "is-available",required_argument,NULL, 'a' },
                { "list",       no_argument, NULL, 'l' },
                { "parameters", required_argument, NULL, 'I' },
                { "comm",       required_argument, NULL, 'r' },
                { NULL, 0, NULL, 0 },
        };
  
-       while ((c = getopt_long(argc, argv, "lhqcI:r:w:WX", longopts, NULL)) != -1) {
+       while ((c = getopt_long(argc, argv, "a:lhqcI:r:w:WX", longopts, NULL)) != -1) {
                switch (c) {
                case 'h':
                        usage(stdout, EXIT_SUCCESS);
+               case 'a':
+                       exit(is_available(optarg)? 0: 1);
                case 'l':
                        list_factories();
                        exit(EXIT_SUCCESS);
                        fdescs[i].close(fdescs[i].fd, fdescs[i].data);
  
        if (factory->free)
 -              factory->free (factory, data);
 +              factory->free(factory, data);
  
        exit(EXIT_SUCCESS);
  }