[CCing Jens because of the discussion below about IOPRIO_WHO_USER below; he may have a comment] [CCing Марк, who independently noted the lack of documentation for IOPRIO_WHO_PROCESS, who==0 .] [CCing Colin McCabe who sent other recent fixes for the ioprio_set.2 page]
On Sat, Dec 17, 2011 at 11:26 PM, Kalle Olavi Niemitalo <k...@iki.fi> wrote: > Package: manpages-dev > Version: 3.32-0.2 > Severity: wishlist > File: /usr/share/man/man2/ioprio_get.2.gz > > The ioprio_get(2) manual page describes the meanings of the which > and who parameters: > >> IOPRIO_WHO_PROCESS >> who is a process ID identifying a single process. >> >> IOPRIO_WHO_PGRP >> who is a process group ID identifying all the members of >> a process group. >> >> IOPRIO_WHO_USER >> who is a user ID identifying all of the processes that >> have a matching real UID. > > The manual page should mention that IOPRIO_WHO_PROCESS and > IOPRIO_WHO_PGRP also allow who==0. Yes. > As implemented in > fs/ioprio.c, who==0 means the calling process or its process > group. The ioprio program in util-linux already uses the > feature. This is worth documenting separately because > e.g. tcsetpgrp does not treat pgrp==0 in that way. Agreed, this should be documented since various APIs interpret pgrp==0 differently. Some (e.g., killpg(2)) are like this syscall, others are not. > For IOPRIO_WHO_USER, the situation is more complex: who==0 means > the root user in ioprio_set but the current user (I think the > real UID of the calling process) in ioprio_get. (That > inconsistency might even be a bug.) So, I'm not sure I'm following the kernel code too well here... @Jens, your comments would be very welovem. In ioprio_get() (Linux 3.5 kernel source file fs/ioprio.c), I see the following: case IOPRIO_WHO_USER: uid = make_kuid(current_user_ns(), who); if (!who) user = current_user(); else user = find_user(uid); if (!user) break; do_each_thread(g, p) { if (!uid_eq(task_uid(p), user->uid)) continue; tmpio = get_task_ioprio(p); if (tmpio < 0) continue; if (ret == -ESRCH) ret = tmpio; else ret = ioprio_best(ret, tmpio); } while_each_thread(g, p); if (who) free_uid(user); break; In ioprio_set(), I see: case IOPRIO_WHO_USER: uid = make_kuid(current_user_ns(), who); if (!uid_valid(uid)) break; if (!who) user = current_user(); else user = find_user(uid); if (!user) break; do_each_thread(g, p) { if (!uid_eq(task_uid(p), uid)) continue; ret = set_task_ioprio(p, ioprio); if (ret) goto free_uid; } while_each_thread(g, p); free_uid: if (who) free_uid(user); break; This suggests to me that you are right Kalle, in your interpretation of who==0 for the IOPRIO_WHO_USER, since ioprio_get() uses current_iser()->uid for its scan while ioprio_get() uses the UID returned by make_kuid() (So, to be precise, I think who==0 in this case means "the UID of the uer who is thye super user in this user namespace"). If that's correct, it does of course need to be documented. I'd be happy to get confirmation from Jens on this point. I suppose that the differing meaning of who==0 for IOPRIO_WHO_USER in ioprio_get() versus ioprio_set() is by design. But if so, like you Kalle, I agree that it's a design point that is likely to surprise users (and surprises here might have security implications). Again, I'd like to get input from Jens. In the meantime, I've applied the patch below to cover the other two cases. Thanks, Michael --- a/man2/ioprio_set.2 +++ b/man2/ioprio_set.2 @@ -56,10 +56,16 @@ is interpreted, and has one of the following values: .B IOPRIO_WHO_PROCESS .I who is a process ID or thread ID identifying a single process or thread. +If +.I who +is 0, then operate on the calling thread. .TP .B IOPRIO_WHO_PGRP .I who is a process group ID identifying all the members of a process group. +If +.I who +is 0, then operate on the process group of which the caller is a member. .TP .B IOPRIO_WHO_USER .I who -- Michael Kerrisk Linux man-pages maintainer; http://www.kernel.org/doc/man-pages/ Author of "The Linux Programming Interface"; http://man7.org/tlpi/ -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org