29 #include <sys/types.h>
31 #include <sys/resource.h>
39 " path Path name of the message queue to create\n"
41 " Note: this program must be run as root in order to enable all tests\n"
44 char *
DEF_MSGS =
"/proc/sys/fs/mqueue/msg_default";
46 char *
MAX_MSGS =
"/proc/sys/fs/mqueue/msg_max";
57 static inline void __set(FILE *stream,
int value,
char *
err_msg);
58 void shutdown(
int exit_val,
char *err_cause,
int line_no);
59 static inline int get(FILE *
stream);
61 static inline void getr(
int type,
struct rlimit *rlim);
62 static inline void setr(
int type,
struct rlimit *rlim);
67 static inline void __set(FILE *stream,
int value,
char *
err_msg)
70 if (
fprintf(stream,
"%d", value) < 0)
75 void shutdown(
int exit_val,
char *err_cause,
int line_no)
77 static int in_shutdown = 0;
87 perror(
"mq_close() during shutdown");
97 "failed to restore saved_def_msgs");
100 "failed to restore saved_def_msgsize");
104 "failed to restore saved_max_msgs");
107 "failed to restore saved_max_msgsize");
109 error(exit_val,
errno,
"%s at %d", err_cause, line_no);
113 static inline int get(FILE *stream)
117 if (fscanf(stream,
"%d", &value) != 1)
118 shutdown(4,
"Error reading /proc entry", __LINE__ - 1);
122 static inline void set(FILE *stream,
int value)
127 if (
fprintf(stream,
"%d", value) < 0)
128 return shutdown(5,
"Failed writing to /proc file",
130 new_value =
get(stream);
131 if (new_value != value)
132 return shutdown(5,
"We didn't get what we wrote to /proc back",
136 static inline void getr(
int type,
struct rlimit *rlim)
139 shutdown(6,
"getrlimit()", __LINE__ - 1);
142 static inline void setr(
int type,
struct rlimit *rlim)
144 if (setrlimit(type, rlim))
145 shutdown(7,
"setrlimit()", __LINE__ - 1);
153 printf(
"Current rlimit value for POSIX message queue bytes is "
154 "unreasonably low,\nincreasing.\n\n");
164 printf(
"Temporarily lowering default queue parameters "
165 "to something that will work\n"
166 "with the current rlimit values.\n\n");
176 printf(
"Temporarily lowering maximum queue parameters "
177 "to something that will work\n"
178 "with the current rlimit values in case this is "
179 "a kernel that ties the default\n"
180 "queue parameters to the maximum queue "
198 int perms = DEFFILEMODE;
202 if (mq_getattr(
queue, result))
203 shutdown(1,
"mq_getattr()", __LINE__);
205 shutdown(1,
"mq_close()", __LINE__);
208 shutdown(1,
"mq_unlink()", __LINE__);
217 static inline int test_queue_fail(
struct mq_attr *attr,
struct mq_attr *result)
220 int perms = DEFFILEMODE;
224 if (mq_getattr(
queue, result))
225 shutdown(1,
"mq_getattr()", __LINE__);
227 shutdown(1,
"mq_close()", __LINE__);
230 shutdown(1,
"mq_unlink()", __LINE__);
239 fprintf(stderr,
"Must pass a valid queue name\n\n");
263 fprintf(stderr,
"Not running as root, but almost all tests "
264 "require root in order to modify\nsystem settings. "
276 shutdown(2,
"Failed to open msg_max", __LINE__);
278 shutdown(2,
"Failed to open msgsize_max", __LINE__);
293 printf(
"\nInitial system state:\n");
295 printf(
"\tRLIMIT_MSGQUEUE(soft):\t\t%d\n", saved_limits.rlim_cur);
296 printf(
"\tRLIMIT_MSGQUEUE(hard):\t\t%d\n", saved_limits.rlim_max);
303 printf(
"\tDefault Message Size:\t\tNot Supported\n");
304 printf(
"\tDefault Queue Size:\t\tNot Supported\n");
310 printf(
"Adjusted system state for testing:\n");
320 printf(
"\n\nTest series 1, behavior when no attr struct "
321 "passed to mq_open:\n");
323 test_queue(
NULL, &result);
324 printf(
"Given sane system settings, mq_open without an attr "
325 "struct succeeds:\tPASS\n");
328 printf(
"Kernel does not support setting the default "
329 "mq attributes,\nbut also doesn't tie the "
330 "defaults to the maximums:\t\t\tPASS\n");
334 test_queue(
NULL, &result);
337 printf(
"Kernel does not support setting the "
338 "default mq attributes and\n"
339 "also ties system wide defaults to "
340 "the system wide maximums:\t\t"
343 printf(
"Kernel does not support setting the "
344 "default mq attributes,\n"
345 "but also doesn't tie the defaults to "
346 "the maximums:\t\t\tPASS\n");
349 printf(
"Kernel supports setting defaults separately from "
350 "maximums:\t\tPASS\n");
355 test_queue(
NULL, &result);
356 printf(
"Given sane values, mq_open without an attr struct "
357 "succeeds:\t\tPASS\n");
360 printf(
"Kernel supports setting defaults, but does "
361 "not actually honor them:\tFAIL\n\n");
368 test_queue(
NULL, &result);
371 printf(
"Kernel supports setting defaults, but "
372 "does not actually honor them:\t"
375 printf(
"Kernel properly honors default setting "
376 "knobs:\t\t\t\tPASS\n");
389 if (test_queue_fail(
NULL, &result)) {
392 printf(
"Kernel properly limits default values "
393 "to lesser of default/max:\t\tPASS\n");
395 printf(
"Kernel does not properly set default "
396 "queue parameters when\ndefaults > "
397 "max:\t\t\t\t\t\t\t\tFAIL\n");
399 printf(
"Kernel fails to open mq because defaults are "
400 "greater than maximums:\tFAIL\n");
406 if (test_queue_fail(
NULL, &result))
407 printf(
"Kernel creates queue even though defaults "
408 "would exceed\nrlimit setting:"
409 "\t\t\t\t\t\t\t\tFAIL\n");
411 printf(
"Kernel properly fails to create queue when "
412 "defaults would\nexceed rlimit:"
413 "\t\t\t\t\t\t\t\tPASS\n");
419 printf(
"\n\nTest series 2, behavior when attr struct is "
420 "passed to mq_open:\n");
427 if (test_queue_fail(&attr, &result))
428 printf(
"Queue open in excess of rlimit max when euid = 0 "
429 "succeeded:\t\tFAIL\n");
431 printf(
"Queue open in excess of rlimit max when euid = 0 "
432 "failed:\t\tPASS\n");
435 if (test_queue_fail(&attr, &result))
436 printf(
"Queue open with mq_maxmsg > limit when euid = 0 "
437 "succeeded:\t\tPASS\n");
439 printf(
"Queue open with mq_maxmsg > limit when euid = 0 "
440 "failed:\t\tFAIL\n");
443 if (test_queue_fail(&attr, &result))
444 printf(
"Queue open with mq_msgsize > limit when euid = 0 "
445 "succeeded:\t\tPASS\n");
447 printf(
"Queue open with mq_msgsize > limit when euid = 0 "
448 "failed:\t\tFAIL\n");
451 if (test_queue_fail(&attr, &result))
452 printf(
"Queue open with total size > 2GB when euid = 0 "
453 "succeeded:\t\tFAIL\n");
455 printf(
"Queue open with total size > 2GB when euid = 0 "
456 "failed:\t\t\tPASS\n");
460 if (test_queue_fail(&attr, &result))
461 printf(
"Queue open in excess of rlimit max when euid = 99 "
462 "succeeded:\t\tFAIL\n");
464 printf(
"Queue open in excess of rlimit max when euid = 99 "
465 "failed:\t\tPASS\n");
468 if (test_queue_fail(&attr, &result))
469 printf(
"Queue open with mq_maxmsg > limit when euid = 99 "
470 "succeeded:\t\tFAIL\n");
472 printf(
"Queue open with mq_maxmsg > limit when euid = 99 "
473 "failed:\t\tPASS\n");
476 if (test_queue_fail(&attr, &result))
477 printf(
"Queue open with mq_msgsize > limit when euid = 99 "
478 "succeeded:\t\tFAIL\n");
480 printf(
"Queue open with mq_msgsize > limit when euid = 99 "
481 "failed:\t\tPASS\n");
484 if (test_queue_fail(&attr, &result))
485 printf(
"Queue open with total size > 2GB when euid = 99 "
486 "succeeded:\t\tFAIL\n");
488 printf(
"Queue open with total size > 2GB when euid = 99 "
489 "failed:\t\t\tPASS\n");