Page MenuHomeFreeBSD

posixmqcontrol: manage POSIX message queues
ClosedPublic

Authored by unitrunker_gmail.com on Feb 12 2024, 6:11 AM.
Tags
None
Referenced Files
Unknown Object (File)
Fri, Apr 26, 12:50 PM
Unknown Object (File)
Mon, Apr 22, 9:10 AM
Unknown Object (File)
Sun, Apr 21, 10:35 PM
Unknown Object (File)
Sun, Apr 21, 6:04 PM
Unknown Object (File)
Fri, Apr 19, 6:16 PM
Unknown Object (File)
Fri, Apr 5, 8:41 AM
Unknown Object (File)
Mar 18 2024, 4:28 PM
Unknown Object (File)
Mar 18 2024, 4:28 PM

Details

Summary

This review introduces a new utility - in the spirit of posixshmcontrol - for managing POSIX message queues.

Summary of features:

  1. Create one or more new queues with the following in common:
    • maximum message size.
    • maximum queue depth.
    • mode bits (rwx).
    • group and user ownership (by ID or name).
    • blocking or non-blocking I/O.
  1. update all of the above attributes to existing queues.
  2. inspect the above attributes on one or more existing queues.
  3. send one or more messages to one or more named queues with optional priority.
  4. receive a message from a named queue.
  5. remove one or more named queues.

This utility requires the mqueuefs kernel module to be loaded. It does NOT require or make use of a mounted mqueuefs.

Justification

  • Create all required queues following boot.
  • De-couple queue administration from application code.
  • Queue depthing monitoring.
  • Access control management with or without a mounted mqueuefs file system.
  • More details can be found in the manual page.
Test Plan

A. sanity checks on queue names - script posixmqcontroltestsane.sh

  • must start with leading slash '/'
  • must not contain more than one slash '/'
  • must not be longer than NAME_MAX characters.

B. create, info, recv, send, and rm subcommands are tested for single queue operation - script posixmqcontroltest8x64.sh

  • verify info on non-existing queue returns an error.
  • create one queue.
  • verify queue exists.
  • send eight distinct messages - with increasing priority.
  • verify queue has eight messages waiting.
  • drain each message from queues - verifying expected order based on priority.
  • verify queue is empty.
  • remove queue.

C. create, info, send, and rm are tested for mutiple queue operations. send is tested for multiple messages - script posixmqcontroltest8qs.sh

  • verify 'info' on non-existing queue returns an error.
  • create eight queues in one 'create' operation.
  • verify eight queues exist in one 'info' operation.
  • send one message to all eight queues in one 'send' operation.
  • verify each queue has one message waiting as one 'info' operation.
  • drain one message from each of eight queues (one at a time).
  • verify each queue is empty as one 'info' operation.
  • remove all queues as one 'rm' operation.

Diff Detail

Repository
rG FreeBSD src repository
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

unitrunker_gmail.com edited the test plan for this revision. (Show Details)
unitrunker_gmail.com edited the summary of this revision. (Show Details)
unitrunker_gmail.com edited the summary of this revision. (Show Details)
usr.bin/posixmqcontrol/posixmqcontrol.c
81
111

You do not check for invalid tail of the text, so for instance 10XXX is parsed as 10. Is this intended?

May be take a look at expand_number(). I am not saying that it must be used, but at least it could be evaluated.

319

I do not think this is good check. You need to ensure that no bits outside 0x666 (perhaps expressed by S_I* constants) are set.

466

Why doing such trip through errno? warn(3) already formats with errno, then I do not see much use of translating each errno value into specific exit code. More, that contradicts Unix tradition of typically returning 1 if there is runtime error, and 2 if there is a bad parameter/config. Then you could just set the exit code locally.

479

How is it possible? If the queue was opened successfully, fd must be valid.

514

I am not sure why not apply the mode always. Anyway, the check should use symbolic
constant like S_IRWXU | S_IRWXG | S_IRWXO.

606

There is something wrong with indent.

647

No need to cast

usr.bin/posixmqcontrol/posixmqcontrol.c
111

Good question. parse_long is for queue depth and message size. The parse_unsigned below is for UID / GID.

3.437 User Name
A string that is used to identify a user; see also User Database. To be portable across systems conforming to POSIX.1-2017, the value is composed of characters from the portable filename character set. The <hyphen-minus> character should not be used as the first character of a portable user name.

If any non-numeric characters appear, I should treat it as a group or user name. However, the parse_group and parse_user functions have already consulted getpwnam / getgrnam before calling parse_unsigned so it can simply fail, leaving the corresponding boolean flag false.

Thanks @kib!

319

See parse_mode. The ranges are enforced there.

466

When mqueuefs related stuff fails, it is sometimes due to the mqueuefs kernel module was not loaded. This is very different from no-such-queue-name or user-not-permitted. The different exit codes help. The person staring at the keyboard can see the text and the script that invoked the utility can capture the exit code. Both have an equal chance of understanding the error.

My reason for different exit codes comes from unpleasant experiences in production where something failed with no clear explanation as to why. I've adopted the opinion that the worst kind of error is the "something bad happened" message (or exit code). Exit code '1' is an example of this.

479

I'd like to confirm this. It would be useful info for the document bug related to mq_getfd_np.

514

I found out recently that setting the S_ISUID or S_ISGID bits is only possible from mq_open. fchmod ignores them on mqueuefs. If I applied always, those bits would be cleared.

I do not know if setting those bits has any value for mqueuefs.

I'll update the code to use the IS_XXXXX bit masks.

647

Thanks @kib. That's 30+ years of C++ sneaking through. Your patience is appreciated.

The O_CREAT variant of mq_open accepts S_ISUID, S_ISGID and S_ISVTX as well as S_IXUSR, S_IXGRP, S_IXOTH "execute" bits. Curiously enough, fchmod ignores S_ISUID and S_ISGID. I've not tried S_ISVTX. I'm inclined to let the tool accept these extra permission bits if only because mq_open takes them.

I've also updated the code to allow a mode value of all zeroes. chmod(1) accepts zero, so this utility can do the same.

usr.bin/posixmqcontrol/posixmqcontrol.c
319

Note that this comment is for a function that was removed.

479

@kib - if you can confirm this is safe behavior, I can update the code here and also the proposed manual page attached to bug https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=273230

647

I missed this (again). One more pass coming.

unitrunker_gmail.com added inline comments.
usr.bin/posixmqcontrol/posixmqcontrol.c
111

Side note: the largest mqueuefs message size is 32768. Maximum number of queues is 64. Unknown on maximum queue depth.

pauamma_gundo.com added inline comments.
usr.bin/posixmqcontrol/posixmqcontrol.1
90

Typo.

Also, what do you mean by "message depth"? mq_open(2) has no mention of that, but mentions a maximum number of messages. Is that what you mean? If so, maybe "queue size" as I suggested below?

103
104
116–119

I would move this paragraph to the DESCRIPTION section and rename the SUMMARY section to NOTES.

117

Avoids "you".

In D43845#1000784, @cy wrote:

Added docs for man page review.

manpages is good too.

usr.bin/posixmqcontrol/posixmqcontrol.1
90

Also, what do you mean by "message depth"?

My intent was "queue depth".

My personal opinion is the word "size" is overloaded. On a mounted mqueuefs, typing 'cat /queue-name' returns the queue size - which is the sum of the length of all messages and MSGSIZE which is maximum size of any individual message. I prefer depth to refer to "number of messages" so that you can have "current queue depth" and "maximum queue depth". I understand this doesn't align with POSIX terminology.

Disclaimer: I've work with IBM MQs since 2005 - where "depth" is the prevailing term.

A quick survey of other message queues (RabbitMQ, MQTT, Kafka) shows "queue size" as the most prevalent.

Let me see what I can do here.

The option to set the maximum message size is -d or --depth. The option -s / --size is already taken for max message size. I've updated the text to use "maximum queue size" and "current queue size" in the general sense and using the word "depth" to specifically refer to the -d / --depth option.

Other ideas considered: -w / --width for maximum message size and -h / --height for maximum number of messages.

Let me know you thoughts.

This revision is now accepted and ready to land.Feb 16 2024, 1:12 AM
kib added inline comments.
usr.bin/posixmqcontrol/posixmqcontrol.c
102
145

IMO writing this as the for() loop would be more compact

  • continue long line
  • simplify for-loop
This revision now requires review to proceed.Feb 17 2024, 5:49 AM
  • continue long line
  • spaces around boolean OR
  • simplify for-loop

Please send me the git-format-patch for this change. Ensure that the author patch metadata is correct.

usr.bin/posixmqcontrol/posixmqcontrol.1
2

It is definitely not.

SPDX-License-Identifier on posixmqcontrol.1

This revision was not accepted when it landed; it landed in state Needs Review.Feb 23 2024, 11:55 PM
This revision was automatically updated to reflect the committed changes.