]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
chrt: support the 'PID:inode' address format
authorChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Tue, 31 Mar 2026 15:38:09 +0000 (11:38 -0400)
committerChristian Goeschel Ndjomouo <cgoesc2@wgu.edu>
Fri, 8 May 2026 18:02:34 +0000 (14:02 -0400)
This patch enables support for the PID:inode address format.
It removes a sentinel value from ctl->pid that controls the PID
parsing behavior and introduces a dedicated variable parse_pid
(member of struct chrt_ctl), which makes the code a bit more
readable and coherent.

Signed-off-by: Christian Goeschel Ndjomouo <cgoesc2@wgu.edu>
schedutils/chrt.1.adoc
schedutils/chrt.c

index b8d8874bca821f47c3d1618370a4cabc26338628..4c6dbde1cde26ed93b6150c746e1ab024135fd4b 100644 (file)
@@ -40,11 +40,12 @@ chrt - manipulate the real-time attributes of a process
 
 *chrt* [options] [_priority_] _command_ [_argument_...]
 
-*chrt --pid* [options] [_priority_] _PID_
+*chrt --pid* [options] [_priority_] _PID_[:_inode_]
 
 == DESCRIPTION
 
-*chrt* sets or retrieves the real-time scheduling attributes of an existing _PID_, or runs _command_ with the given attributes.
+*chrt* sets or retrieves the real-time scheduling attributes of an existing _PID_[:_inode_], or runs _command_ with the given attributes.
+The _inode_ uniquely identifies the process identity in the pidfs. To retrieve a process's inode number you can use the *getino*(1) utility.
 
 == POLICY OPTIONS
 
@@ -118,12 +119,12 @@ ____
 //TRANSLATORS: Keep {colon} untranslated
 You can also retrieve the real-time attributes of an existing task{colon}::
 ____
-*chrt --pid* _PID_
+*chrt --pid* _PID_[:_inode_]
 ____
 //TRANSLATORS: Keep {colon} untranslated
 Or set them{colon}::
 ____
-*chrt --pid* _policy-option priority PID_
+*chrt --pid* _policy-option_ _priority_ _PID_[:_inode_]
 ____
 For example, to set the scheduling policy to *SCHED_RR* (round-robin) and the priority to *30* for process *1234*{colon}::
 ____
@@ -131,11 +132,11 @@ ____
 ____
 Reset priorities to default for a process{colon}::
 ____
-*chrt --pid -o 0* _PID_
+*chrt --pid -o 0* _PID_[:_inode_]
 ____
 Set a custom slice of 1 ms for a *SCHED_OTHER* task (priority is optional for policies other than *SCHED_FIFO* and *SCHED_RR*){colon}::
 ____
-*chrt --pid -o -T 1000000* _PID_
+*chrt --pid -o -T 1000000* _PID_[:_inode_]
 ____
 See *sched*(7) for a detailed discussion of the different scheduler classes and how they interact.
 
@@ -159,7 +160,8 @@ mailto:kzak@redhat.com[Karel Zak]
 *nice*(1),
 *renice*(1),
 *taskset*(1),
-*sched*(7)
+*sched*(7),
+*getino*(1)
 
 See *sched_setscheduler*(2) for a description of the Linux scheduling scheme.
 
index 5ba9964c1dd6c4465c2715fc5984c4841c432da0..3e4ea41d51b17bb5ab461a774339f059d75f5970 100644 (file)
 #include "strutils.h"
 #include "procfs.h"
 #include "sched_attr.h"
-
+#include "pidutils.h"
+#include "pidfd-utils.h"
 
 /* control struct */
 struct chrt_ctl {
-       pid_t   pid;
-       int     policy;                         /* SCHED_* */
-       int     priority;
+       pid_t           pid;
+       uint64_t        pidfd_ino;
+       int             pidfd;
+       int             policy;                         /* SCHED_* */
+       int             priority;
 
        uint64_t runtime;                       /* --sched-* options */
        uint64_t deadline;
@@ -50,21 +53,30 @@ struct chrt_ctl {
        unsigned int all_tasks : 1,             /* all threads of the PID */
                     reset_on_fork : 1,         /* SCHED_RESET_ON_FORK or SCHED_FLAG_RESET_ON_FORK */
                     altered : 1,               /* sched_set**() used */
-                    verbose : 1;               /* verbose output */
+                    verbose : 1,               /* verbose output */
+                    parse_pid : 1;             /* expect a PID as last command line argument */
 };
 
 static void __attribute__((__noreturn__)) usage(void)
 {
        FILE *out = stdout;
+       char *pid_arg = NULL;
+
+#ifdef USE_PIDFD_INO_SUPPORT
+       pid_arg = "PID[:inode]";
+#else
+       pid_arg = "PID";
+#endif
+
 
        fputs(_("Show or change the real-time scheduling attributes of a process.\n"), out);
        fputs(USAGE_SEPARATOR, out);
-       fputs(_("Set policy:\n"
+       fprintf(out, _("Set policy:\n"
                " chrt [options] [<priority>] <command> [<argument>...]\n"
-               " chrt --pid <policy-option> [options] [<priority>] <PID>\n"), out);
+               " chrt --pid <policy-option> [options] [<priority>] <%s>\n"), pid_arg);
        fputs(USAGE_SEPARATOR, out);
-       fputs(_("Get policy:\n"
-               " chrt --pid <PID>\n"), out);
+       fprintf(out, _("Get policy:\n"
+               " chrt --pid <%s>\n"), pid_arg);
 
        fputs(USAGE_SEPARATOR, out);
        fputs(_("Policy options:\n"), out);
@@ -397,7 +409,13 @@ static void set_sched(struct chrt_ctl *ctl)
 
 int main(int argc, char **argv)
 {
-       struct chrt_ctl _ctl = { .pid = -1, .policy = SCHED_RR }, *ctl = &_ctl;
+       struct chrt_ctl _ctl = {
+               .parse_pid = 0,
+               .pid = 0,
+               .pidfd_ino = 0,
+               .pidfd = -1,
+               .policy = SCHED_RR
+       }, *ctl = &_ctl;
        int c;
        bool policy_given = false, need_prio = false;
 
@@ -474,7 +492,7 @@ int main(int argc, char **argv)
                        policy_given = true;
                        break;
                case 'p':
-                       ctl->pid = 0;  /* indicate that a PID is expected */
+                       ctl->parse_pid = 1;  /* indicate that a PID is expected */
                        break;
                case 'r':
                        ctl->policy = SCHED_RR;
@@ -509,10 +527,11 @@ int main(int argc, char **argv)
        }
 
        /* If option --pid was given, parse the very last argument as a PID. */
-       if (ctl->pid == 0) {
+       if (ctl->parse_pid) {
                errno = 0;
-               /* strtopid_or_err() is not suitable here, as 0 can be passed. */
-               ctl->pid = strtos32_or_err(argv[argc - 1], _("invalid PID argument"));
+               ul_parse_pid_str_or_err(argv[argc - 1], &ctl->pid, &ctl->pidfd_ino, UL_PID_ZERO);
+               if (ctl->pidfd_ino > 0)
+                       ctl->pidfd = ul_get_valid_pidfd_or_err(ctl->pid, ctl->pidfd_ino);
 
                /* If no policy nor priority was given, show current settings. */
                if (!policy_given && argc - optind == 1) {
@@ -524,21 +543,21 @@ int main(int argc, char **argv)
        if (ctl->policy == SCHED_RR)
                need_prio = true;
 
-       if (ctl->pid > -1 && ctl->verbose)
+       if (ctl->parse_pid && ctl->verbose)
                show_sched_info(ctl);
 
-       if (argc - optind > 1 && (ctl->pid > -1 || isdigit_string(argv[optind]))) {
+       if (argc - optind > 1 && (ctl->parse_pid || isdigit_string(argv[optind]))) {
                errno = 0;
                ctl->priority = strtos32_or_err(argv[optind], _("invalid priority argument"));
-
                optind++;
-       } else if (need_prio && ctl->pid == -1 && isdigit_string(argv[optind]))
+       } else if (need_prio && !ctl->parse_pid && isdigit_string(argv[optind])) {
                errx(EXIT_FAILURE, _("no command or priority specified"));
-       else if (need_prio)
+       } else if (need_prio) {
                errx(EXIT_FAILURE, _("policy %s requires a priority argument"),
                                        get_policy_name(ctl->policy));
-       else
+       } else {
                ctl->priority = 0;
+       }
 
        if (ctl->runtime && !supports_runtime_param(ctl->policy))
                errx(EXIT_FAILURE, _("--sched-runtime option is supported for %s"),
@@ -562,19 +581,20 @@ int main(int argc, char **argv)
        if (ctl->deadline || ctl->period)
                errx(EXIT_FAILURE, _("SCHED_DEADLINE is unsupported"));
 #endif
-       if (ctl->pid == -1)
-               ctl->pid = 0;
        if (ctl->priority < sched_get_priority_min(ctl->policy) ||
-           sched_get_priority_max(ctl->policy) < ctl->priority)
+                       sched_get_priority_max(ctl->policy) < ctl->priority)
                errx(EXIT_FAILURE,
-                    _("unsupported priority value for the policy: %d: see --max for valid range"),
-                    ctl->priority);
+               _("unsupported priority value for the policy: %d: see --max for valid range"),
+                       ctl->priority);
        set_sched(ctl);
 
        if (ctl->verbose)
                show_sched_info(ctl);
 
-       if (!ctl->pid) {
+       if (ctl->pidfd >= 0)
+               close(ctl->pidfd);
+
+       if (!ctl->parse_pid) {
                argv += optind;
 
                if (argv[0] && strcmp(argv[0], "--") == 0)