Craig Small schrob: > Hi Jan, > The issue is that the command name is increasing in length in the kernel. > So the utilities needed to increase their command name length as well. > > ps -o comm <PID> > > Would show you the field it's trying to match against and unless you have a > very recent kernel it will be truncated to 16 characters.
Yes, I was aware of that limitation¹. I just think killall (and pgrep, tbh) should handle that, so I don't have to count letters when I'm typing into my shell, and can write shellscripts that work regardless of what the kernel limit is. And I think it's a good thing that the kernel is increasing that limit. (To what? And might we even get another increase in the very far future?) > However leaving psmisc alone is not the answer either because when you do > eventually get a newer kernel, the matching will fail again because you > will have no way of specifying names longer than 16 characters. Agreed, that's not a satisfactory outcome. > Strictly speaking killall is working correctly. You're specifying a name > longer than 16 characters and the process command name is trucated to 16 > characters so it's not a match. It is a bit annoying and unexpected though. Well, even more strictly speaking killall(1) documents the --exact switch to enable the behaviour you describe, and explains that without that switch and with the whole command name unavailable, "killall will kill everything that matches within the first 15 characters." So at the very least the documentation is wrong now. ;-P I guess the kernel doesn't export the length limit (TASK_COMM_LEN) somehow? What if killall tries to set its own comm field to something very large, reads it back and takes the length of that? (If that is expensive, then do it only if the command name is a prefix of the given name.) Because once you know the kernel limit, you can just truncate the given name to that length and compare. > An idea I have been toying with is to check if the command name are exactly > 16 characters and the given name is 16 characters or more and match the > first 16 as well. > That way it's going to sort of conditionally work like before. I'll need to > think about false positives and the most efficient way of doing it but that > could solve things I think. Well, false positives in your scheme can not occur on old kernels, because everything is <=16 chars anyway. And on new kernels, they occur iff the command name is truly 16 chars, and a prefix of the given name. And if that situation had happened on an old kernel, you'd have decided to kill the process, too! So I don't think there's a way that scheme can break setups that worked on old kernels. Worst case, you fail to take advantage of the additional info the new kernel gives you. About efficiency, I think figuring out whether A is a equal to B, a proper prefix of B, or neither (and returning the length of A in the 2nd case) needn't be more expensive than strcmp²: while ( *a != '\0' && *b != '\0' && *a == *b) { ++a; ++b; } /* inspect *a and *b and return appropriately */ And in the proper prefix case, you can compare the length to TASK_COMM_LEN (if you can figure it out), or 16 (your scheme) and that's it. Does that sound reasonable? regards, Jan ¹ except that there's apparently some confusion about whether those 16 characters include the terminating nul. proc(5) and you seem to think it doesn't, killall(1) and my kernel seem to think it does. :D ² well, strcmp might be carefully hand-optimized assembler code. But since we're comparing strings of length ~16, I think we can manage without that. ;)
signature.asc
Description: PGP signature