kdbus: the driver, original and non-working
[platform/kernel/linux-exynos.git] / tools / testing / selftests / kdbus / kdbus-test.c
1 #include <errno.h>
2 #include <stdio.h>
3 #include <string.h>
4 #include <fcntl.h>
5 #include <stdlib.h>
6 #include <stddef.h>
7 #include <time.h>
8 #include <unistd.h>
9 #include <stdint.h>
10 #include <assert.h>
11 #include <getopt.h>
12 #include <stdbool.h>
13 #include <signal.h>
14 #include <sys/mount.h>
15 #include <sys/prctl.h>
16 #include <sys/wait.h>
17 #include <sys/syscall.h>
18 #include <sys/eventfd.h>
19 #include <linux/sched.h>
20
21 #include "kdbus-util.h"
22 #include "kdbus-enum.h"
23 #include "kdbus-test.h"
24
25 enum {
26         TEST_CREATE_BUS         = 1 << 0,
27         TEST_CREATE_CONN        = 1 << 1,
28         TEST_CREATE_CAN_FAIL    = 1 << 2,
29 };
30
31 struct kdbus_test {
32         const char *name;
33         const char *desc;
34         int (*func)(struct kdbus_test_env *env);
35         unsigned int flags;
36 };
37
38 struct kdbus_test_args {
39         bool mntns;
40         bool pidns;
41         bool userns;
42         char *uid_map;
43         char *gid_map;
44         int loop;
45         int wait;
46         int fork;
47         int tap_output;
48         char *module;
49         char *root;
50         char *test;
51         char *busname;
52         char *mask_param_path;
53 };
54
55 static const struct kdbus_test tests[] = {
56         {
57                 .name   = "bus-make",
58                 .desc   = "bus make functions",
59                 .func   = kdbus_test_bus_make,
60                 .flags  = 0,
61         },
62         {
63                 .name   = "hello",
64                 .desc   = "the HELLO command",
65                 .func   = kdbus_test_hello,
66                 .flags  = TEST_CREATE_BUS,
67         },
68         {
69                 .name   = "byebye",
70                 .desc   = "the BYEBYE command",
71                 .func   = kdbus_test_byebye,
72                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
73         },
74         {
75                 .name   = "chat",
76                 .desc   = "a chat pattern",
77                 .func   = kdbus_test_chat,
78                 .flags  = TEST_CREATE_BUS,
79         },
80         {
81                 .name   = "daemon",
82                 .desc   = "a simple daemon",
83                 .func   = kdbus_test_daemon,
84                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
85         },
86         {
87                 .name   = "fd-passing",
88                 .desc   = "file descriptor passing",
89                 .func   = kdbus_test_fd_passing,
90                 .flags  = TEST_CREATE_BUS,
91         },
92         {
93                 .name   = "endpoint",
94                 .desc   = "custom endpoint",
95                 .func   = kdbus_test_custom_endpoint,
96                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
97         },
98         {
99                 .name   = "monitor",
100                 .desc   = "monitor functionality",
101                 .func   = kdbus_test_monitor,
102                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
103         },
104         {
105                 .name   = "name-basics",
106                 .desc   = "basic name registry functions",
107                 .func   = kdbus_test_name_basic,
108                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
109         },
110         {
111                 .name   = "name-conflict",
112                 .desc   = "name registry conflict details",
113                 .func   = kdbus_test_name_conflict,
114                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
115         },
116         {
117                 .name   = "name-queue",
118                 .desc   = "queuing of names",
119                 .func   = kdbus_test_name_queue,
120                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
121         },
122         {
123                 .name   = "message-basic",
124                 .desc   = "basic message handling",
125                 .func   = kdbus_test_message_basic,
126                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
127         },
128         {
129                 .name   = "message-prio",
130                 .desc   = "handling of messages with priority",
131                 .func   = kdbus_test_message_prio,
132                 .flags  = TEST_CREATE_BUS,
133         },
134         {
135                 .name   = "message-quota",
136                 .desc   = "message quotas are enforced",
137                 .func   = kdbus_test_message_quota,
138                 .flags  = TEST_CREATE_BUS,
139         },
140         {
141                 .name   = "memory-access",
142                 .desc   = "memory access",
143                 .func   = kdbus_test_memory_access,
144                 .flags  = TEST_CREATE_BUS,
145         },
146         {
147                 .name   = "timeout",
148                 .desc   = "timeout",
149                 .func   = kdbus_test_timeout,
150                 .flags  = TEST_CREATE_BUS,
151         },
152         {
153                 .name   = "send",
154                 .desc   = "send",
155                 .func   = kdbus_test_send,
156                 .flags  = TEST_CREATE_CONN | TEST_CREATE_CAN_FAIL,
157         },
158         {
159                 .name   = "sync-byebye",
160                 .desc   = "synchronous replies vs. BYEBYE",
161                 .func   = kdbus_test_sync_byebye,
162                 .flags  = TEST_CREATE_BUS,
163         },
164         {
165                 .name   = "sync-reply",
166                 .desc   = "synchronous replies",
167                 .func   = kdbus_test_sync_reply,
168                 .flags  = TEST_CREATE_BUS,
169         },
170         {
171                 .name   = "message-free",
172                 .desc   = "freeing of memory",
173                 .func   = kdbus_test_free,
174                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
175         },
176         {
177                 .name   = "connection-info",
178                 .desc   = "retrieving connection information",
179                 .func   = kdbus_test_conn_info,
180                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
181         },
182         {
183                 .name   = "connection-update",
184                 .desc   = "updating connection information",
185                 .func   = kdbus_test_conn_update,
186                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
187         },
188         {
189                 .name   = "writable-pool",
190                 .desc   = "verifying pools are never writable",
191                 .func   = kdbus_test_writable_pool,
192                 .flags  = TEST_CREATE_BUS,
193         },
194         {
195                 .name   = "policy",
196                 .desc   = "policy",
197                 .func   = kdbus_test_policy,
198                 .flags  = TEST_CREATE_BUS,
199         },
200         {
201                 .name   = "policy-priv",
202                 .desc   = "unprivileged bus access",
203                 .func   = kdbus_test_policy_priv,
204                 .flags  = TEST_CREATE_BUS,
205         },
206         {
207                 .name   = "policy-ns",
208                 .desc   = "policy in user namespaces",
209                 .func   = kdbus_test_policy_ns,
210                 .flags  = TEST_CREATE_BUS,
211         },
212         {
213                 .name   = "metadata-ns",
214                 .desc   = "metadata in different namespaces",
215                 .func   = kdbus_test_metadata_ns,
216                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
217         },
218         {
219                 .name   = "match-id-add",
220                 .desc   = "adding of matches by id",
221                 .func   = kdbus_test_match_id_add,
222                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
223         },
224         {
225                 .name   = "match-id-remove",
226                 .desc   = "removing of matches by id",
227                 .func   = kdbus_test_match_id_remove,
228                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
229         },
230         {
231                 .name   = "match-replace",
232                 .desc   = "replace of matches with the same cookie",
233                 .func   = kdbus_test_match_replace,
234                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
235         },
236         {
237                 .name   = "match-name-add",
238                 .desc   = "adding of matches by name",
239                 .func   = kdbus_test_match_name_add,
240                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
241         },
242         {
243                 .name   = "match-name-remove",
244                 .desc   = "removing of matches by name",
245                 .func   = kdbus_test_match_name_remove,
246                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
247         },
248         {
249                 .name   = "match-name-change",
250                 .desc   = "matching for name changes",
251                 .func   = kdbus_test_match_name_change,
252                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
253         },
254         {
255                 .name   = "match-bloom",
256                 .desc   = "matching with bloom filters",
257                 .func   = kdbus_test_match_bloom,
258                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
259         },
260         {
261                 .name   = "activator",
262                 .desc   = "activator connections",
263                 .func   = kdbus_test_activator,
264                 .flags  = TEST_CREATE_BUS | TEST_CREATE_CONN,
265         },
266         {
267                 .name   = "benchmark",
268                 .desc   = "benchmark",
269                 .func   = kdbus_test_benchmark,
270                 .flags  = TEST_CREATE_BUS,
271         },
272         {
273                 .name   = "benchmark-nomemfds",
274                 .desc   = "benchmark without using memfds",
275                 .func   = kdbus_test_benchmark_nomemfds,
276                 .flags  = TEST_CREATE_BUS,
277         },
278         {
279                 .name   = "benchmark-uds",
280                 .desc   = "benchmark comparison to UDS",
281                 .func   = kdbus_test_benchmark_uds,
282                 .flags  = TEST_CREATE_BUS,
283         },
284         {
285                 /* Last test */
286                 .name   = "attach-flags",
287                 .desc   = "attach flags mask",
288                 .func   = kdbus_test_attach_flags,
289                 .flags  = 0,
290         },
291 };
292
293 #define N_TESTS ((int) (sizeof(tests) / sizeof(tests[0])))
294
295 static int test_prepare_env(const struct kdbus_test *t,
296                             const struct kdbus_test_args *args,
297                             struct kdbus_test_env *env)
298 {
299         if (t->flags & TEST_CREATE_BUS) {
300                 char *s;
301                 char *n = NULL;
302                 int ret;
303
304                 asprintf(&s, "%s/control", args->root);
305
306                 env->control_fd = open(s, O_RDWR);
307                 free(s);
308                 ASSERT_RETURN(env->control_fd >= 0);
309
310                 if (!args->busname) {
311                         n = unique_name("test-bus");
312                         ASSERT_RETURN(n);
313                 }
314
315                 ret = kdbus_create_bus(env->control_fd,
316                                        args->busname ?: n,
317                                        _KDBUS_ATTACH_ALL,
318                                        _KDBUS_ATTACH_ALL, &s);
319                 free(n);
320                 ASSERT_RETURN((ret == 0) || (t->flags & TEST_CREATE_CAN_FAIL));
321
322                 asprintf(&env->buspath, "%s/%s/bus", args->root, s);
323                 free(s);
324         }
325
326         if (t->flags & TEST_CREATE_CONN) {
327                 if (!env->buspath) {
328                         char *s = NULL;
329                         char *n = NULL;
330                         int ret;
331
332                         if (!args->busname) {
333                                 n = unique_name("test-bus");
334                                 ASSERT_RETURN(n);
335                         }
336
337                         ret = kdbus_create_bus(-1,
338                                                args->busname ?: n,
339                                                0,
340                                                0, &s);
341                         free(n);
342                         ASSERT_RETURN(ret == 0);
343
344                         asprintf(&env->buspath, "%s/%s/bus", args->root, s);
345                         free(s);
346                 }
347                 ASSERT_RETURN(env->buspath);
348                 env->conn = kdbus_hello(env->buspath, 0, NULL, 0);
349                 ASSERT_RETURN(env->conn || (t->flags & TEST_CREATE_CAN_FAIL));
350         }
351
352         env->root = args->root;
353         env->module = args->module;
354         env->mask_param_path = args->mask_param_path;
355
356         return 0;
357 }
358
359 void test_unprepare_env(const struct kdbus_test *t, struct kdbus_test_env *env)
360 {
361         if (env->conn) {
362                 kdbus_conn_free(env->conn);
363                 env->conn = NULL;
364         }
365
366         if (env->control_fd >= 0) {
367                 close(env->control_fd);
368                 env->control_fd = -1;
369         }
370
371         if (env->buspath) {
372                 free(env->buspath);
373                 env->buspath = NULL;
374         }
375 }
376
377 static int test_run(const struct kdbus_test *t,
378                     const struct kdbus_test_args *kdbus_args,
379                     int wait)
380 {
381         int ret;
382         struct kdbus_test_env env = {};
383
384         ret = test_prepare_env(t, kdbus_args, &env);
385         if (ret != TEST_OK)
386                 return ret;
387
388         if (wait > 0) {
389                 printf("Sleeping %d seconds before running test ...\n", wait);
390                 sleep(wait);
391         }
392
393         ret = t->func(&env);
394         test_unprepare_env(t, &env);
395         return ret;
396 }
397
398 static int test_run_forked(const struct kdbus_test *t,
399                            const struct kdbus_test_args *kdbus_args,
400                            int wait)
401 {
402         int ret;
403         pid_t pid;
404
405         pid = fork();
406         if (pid < 0) {
407                 return TEST_ERR;
408         } else if (pid == 0) {
409                 ret = test_run(t, kdbus_args, wait);
410                 _exit(ret);
411         }
412
413         pid = waitpid(pid, &ret, 0);
414         if (pid <= 0)
415                 return TEST_ERR;
416         else if (!WIFEXITED(ret))
417                 return TEST_ERR;
418         else
419                 return WEXITSTATUS(ret);
420 }
421
422 static void print_test_result(int ret)
423 {
424         switch (ret) {
425         case TEST_OK:
426                 printf("OK");
427                 break;
428         case TEST_SKIP:
429                 printf("SKIPPED");
430                 break;
431         case TEST_ERR:
432                 printf("ERROR");
433                 break;
434         }
435 }
436
437 static int start_all_tests(struct kdbus_test_args *kdbus_args)
438 {
439         int ret;
440         unsigned int fail_cnt = 0;
441         unsigned int skip_cnt = 0;
442         unsigned int ok_cnt = 0;
443         unsigned int i;
444
445         if (kdbus_args->tap_output) {
446                 printf("1..%d\n", N_TESTS);
447                 fflush(stdout);
448         }
449
450         kdbus_util_verbose = false;
451
452         for (i = 0; i < N_TESTS; i++) {
453                 const struct kdbus_test *t = tests + i;
454
455                 if (!kdbus_args->tap_output) {
456                         unsigned int n;
457
458                         printf("Testing %s (%s) ", t->desc, t->name);
459                         for (n = 0; n < 60 - strlen(t->desc) - strlen(t->name); n++)
460                                 printf(".");
461                         printf(" ");
462                 }
463
464                 ret = test_run_forked(t, kdbus_args, 0);
465                 switch (ret) {
466                 case TEST_OK:
467                         ok_cnt++;
468                         break;
469                 case TEST_SKIP:
470                         skip_cnt++;
471                         break;
472                 case TEST_ERR:
473                         fail_cnt++;
474                         break;
475                 }
476
477                 if (kdbus_args->tap_output) {
478                         printf("%sok %d - %s%s (%s)\n",
479                                (ret == TEST_ERR) ? "not " : "", i + 1,
480                                (ret == TEST_SKIP) ? "# SKIP " : "",
481                                t->desc, t->name);
482                         fflush(stdout);
483                 } else {
484                         print_test_result(ret);
485                         printf("\n");
486                 }
487         }
488
489         if (kdbus_args->tap_output)
490                 printf("Failed %d/%d tests, %.2f%% okay\n", fail_cnt, N_TESTS,
491                        100.0 - (fail_cnt * 100.0) / ((float) N_TESTS));
492         else
493                 printf("\nSUMMARY: %u tests passed, %u skipped, %u failed\n",
494                        ok_cnt, skip_cnt, fail_cnt);
495
496         return fail_cnt > 0 ? TEST_ERR : TEST_OK;
497 }
498
499 static int start_one_test(struct kdbus_test_args *kdbus_args)
500 {
501         int i, ret;
502         bool test_found = false;
503
504         for (i = 0; i < N_TESTS; i++) {
505                 const struct kdbus_test *t = tests + i;
506
507                 if (strcmp(t->name, kdbus_args->test))
508                         continue;
509
510                 do {
511                         test_found = true;
512                         if (kdbus_args->fork)
513                                 ret = test_run_forked(t, kdbus_args,
514                                                       kdbus_args->wait);
515                         else
516                                 ret = test_run(t, kdbus_args,
517                                                kdbus_args->wait);
518
519                         printf("Testing %s: ", t->desc);
520                         print_test_result(ret);
521                         printf("\n");
522
523                         if (ret != TEST_OK)
524                                 break;
525                 } while (kdbus_args->loop);
526
527                 return ret;
528         }
529
530         if (!test_found) {
531                 printf("Unknown test-id '%s'\n", kdbus_args->test);
532                 return TEST_ERR;
533         }
534
535         return TEST_OK;
536 }
537
538 static void usage(const char *argv0)
539 {
540         unsigned int i, j;
541
542         printf("Usage: %s [options]\n"
543                "Options:\n"
544                "\t-a, --tap             Output test results in TAP format\n"
545                "\t-m, --module <module> Kdbus module name\n"
546                "\t-x, --loop            Run in a loop\n"
547                "\t-f, --fork            Fork before running a test\n"
548                "\t-h, --help            Print this help\n"
549                "\t-r, --root <root>     Toplevel of the kdbus hierarchy\n"
550                "\t-t, --test <test-id>  Run one specific test only, in verbose mode\n"
551                "\t-b, --bus <busname>   Instead of generating a random bus name, take <busname>.\n"
552                "\t-w, --wait <secs>     Wait <secs> before actually starting test\n"
553                "\t    --mntns           New mount namespace\n"
554                "\t    --pidns           New PID namespace\n"
555                "\t    --userns          New user namespace\n"
556                "\t    --uidmap uid_map  UID map for user namespace\n"
557                "\t    --gidmap gid_map  GID map for user namespace\n"
558                "\n", argv0);
559
560         printf("By default, all test are run once, and a summary is printed.\n"
561                "Available tests for --test:\n\n");
562
563         for (i = 0; i < N_TESTS; i++) {
564                 const struct kdbus_test *t = tests + i;
565
566                 printf("\t%s", t->name);
567
568                 for (j = 0; j < 24 - strlen(t->name); j++)
569                         printf(" ");
570
571                 printf("Test %s\n", t->desc);
572         }
573
574         printf("\n");
575         printf("Note that some tests may, if run specifically by --test, "
576                "behave differently, and not terminate by themselves.\n");
577
578         exit(EXIT_FAILURE);
579 }
580
581 void print_kdbus_test_args(struct kdbus_test_args *args)
582 {
583         if (args->userns || args->pidns || args->mntns)
584                 printf("# Starting tests in new %s%s%s namespaces%s\n",
585                         args->mntns ? "MOUNT " : "",
586                         args->pidns ? "PID " : "",
587                         args->userns ? "USER " : "",
588                         args->mntns ? ", kdbusfs will be remounted" : "");
589         else
590                 printf("# Starting tests in the same namespaces\n");
591 }
592
593 void print_metadata_support(void)
594 {
595         bool no_meta_audit, no_meta_cgroups, no_meta_seclabel;
596
597         /*
598          * KDBUS_ATTACH_CGROUP, KDBUS_ATTACH_AUDIT and
599          * KDBUS_ATTACH_SECLABEL
600          */
601         no_meta_audit = !config_auditsyscall_is_enabled();
602         no_meta_cgroups = !config_cgroups_is_enabled();
603         no_meta_seclabel = !config_security_is_enabled();
604
605         if (no_meta_audit | no_meta_cgroups | no_meta_seclabel)
606                 printf("# Starting tests without %s%s%s metadata support\n",
607                        no_meta_audit ? "AUDIT " : "",
608                        no_meta_cgroups ? "CGROUP " : "",
609                        no_meta_seclabel ? "SECLABEL " : "");
610         else
611                 printf("# Starting tests with full metadata support\n");
612 }
613
614 int run_tests(struct kdbus_test_args *kdbus_args)
615 {
616         int ret;
617         static char control[4096];
618
619         snprintf(control, sizeof(control), "%s/control", kdbus_args->root);
620
621         if (access(control, W_OK) < 0) {
622                 printf("Unable to locate control node at '%s'.\n",
623                         control);
624                 return TEST_ERR;
625         }
626
627         if (kdbus_args->test) {
628                 ret = start_one_test(kdbus_args);
629         } else {
630                 do {
631                         ret = start_all_tests(kdbus_args);
632                         if (ret != TEST_OK)
633                                 break;
634                 } while (kdbus_args->loop);
635         }
636
637         return ret;
638 }
639
640 static void nop_handler(int sig) {}
641
642 static int test_prepare_mounts(struct kdbus_test_args *kdbus_args)
643 {
644         int ret;
645         char kdbusfs[64] = {'\0'};
646
647         snprintf(kdbusfs, sizeof(kdbusfs), "%sfs", kdbus_args->module);
648
649         /* make current mount slave */
650         ret = mount(NULL, "/", NULL, MS_SLAVE|MS_REC, NULL);
651         if (ret < 0) {
652                 ret = -errno;
653                 printf("error mount() root: %d (%m)\n", ret);
654                 return ret;
655         }
656
657         /* Remount procfs since we need it in our tests */
658         if (kdbus_args->pidns) {
659                 ret = mount("proc", "/proc", "proc",
660                             MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
661                 if (ret < 0) {
662                         ret = -errno;
663                         printf("error mount() /proc : %d (%m)\n", ret);
664                         return ret;
665                 }
666         }
667
668         /* Remount kdbusfs */
669         ret = mount(kdbusfs, kdbus_args->root, kdbusfs,
670                     MS_NOSUID|MS_NOEXEC|MS_NODEV, NULL);
671         if (ret < 0) {
672                 ret = -errno;
673                 printf("error mount() %s :%d (%m)\n", kdbusfs, ret);
674                 return ret;
675         }
676
677         return 0;
678 }
679
680 int run_tests_in_namespaces(struct kdbus_test_args *kdbus_args)
681 {
682         int ret;
683         int efd = -1;
684         int status;
685         pid_t pid, rpid;
686         struct sigaction oldsa;
687         struct sigaction sa = {
688                 .sa_handler = nop_handler,
689                 .sa_flags = SA_NOCLDSTOP,
690         };
691
692         efd = eventfd(0, EFD_CLOEXEC);
693         if (efd < 0) {
694                 ret = -errno;
695                 printf("eventfd() failed: %d (%m)\n", ret);
696                 return TEST_ERR;
697         }
698
699         ret = sigaction(SIGCHLD, &sa, &oldsa);
700         if (ret < 0) {
701                 ret = -errno;
702                 printf("sigaction() failed: %d (%m)\n", ret);
703                 return TEST_ERR;
704         }
705
706         /* setup namespaces */
707         pid = syscall(__NR_clone, SIGCHLD|
708                       (kdbus_args->userns ? CLONE_NEWUSER : 0) |
709                       (kdbus_args->mntns ? CLONE_NEWNS : 0) |
710                       (kdbus_args->pidns ? CLONE_NEWPID : 0), NULL);
711         if (pid < 0) {
712                 printf("clone() failed: %d (%m)\n", -errno);
713                 return TEST_ERR;
714         }
715
716         if (pid == 0) {
717                 eventfd_t event_status = 0;
718
719                 ret = prctl(PR_SET_PDEATHSIG, SIGKILL);
720                 if (ret < 0) {
721                         ret = -errno;
722                         printf("error prctl(): %d (%m)\n", ret);
723                         _exit(TEST_ERR);
724                 }
725
726                 /* reset sighandlers of childs */
727                 ret = sigaction(SIGCHLD, &oldsa, NULL);
728                 if (ret < 0) {
729                         ret = -errno;
730                         printf("sigaction() failed: %d (%m)\n", ret);
731                         _exit(TEST_ERR);
732                 }
733
734                 ret = eventfd_read(efd, &event_status);
735                 if (ret < 0 || event_status != 1) {
736                         printf("error eventfd_read()\n");
737                         _exit(TEST_ERR);
738                 }
739
740                 if (kdbus_args->mntns) {
741                         ret = test_prepare_mounts(kdbus_args);
742                         if (ret < 0) {
743                                 printf("error preparing mounts\n");
744                                 _exit(TEST_ERR);
745                         }
746                 }
747
748                 ret = run_tests(kdbus_args);
749                 _exit(ret);
750         }
751
752         /* Setup userns mapping */
753         if (kdbus_args->userns) {
754                 ret = userns_map_uid_gid(pid, kdbus_args->uid_map,
755                                          kdbus_args->gid_map);
756                 if (ret < 0) {
757                         printf("error mapping uid and gid in userns\n");
758                         eventfd_write(efd, 2);
759                         return TEST_ERR;
760                 }
761         }
762
763         ret = eventfd_write(efd, 1);
764         if (ret < 0) {
765                 ret = -errno;
766                 printf("error eventfd_write(): %d (%m)\n", ret);
767                 return TEST_ERR;
768         }
769
770         rpid = waitpid(pid, &status, 0);
771         ASSERT_RETURN_VAL(rpid == pid, TEST_ERR);
772
773         close(efd);
774
775         if (!WIFEXITED(status) || WEXITSTATUS(status) != 0)
776                 return TEST_ERR;
777
778         return TEST_OK;
779 }
780
781 int start_tests(struct kdbus_test_args *kdbus_args)
782 {
783         int ret;
784         bool namespaces;
785         uint64_t kdbus_param_mask;
786         static char fspath[4096], parampath[4096];
787
788         namespaces = (kdbus_args->mntns || kdbus_args->pidns ||
789                       kdbus_args->userns);
790
791         /* for pidns we need mntns set */
792         if (kdbus_args->pidns && !kdbus_args->mntns) {
793                 printf("Failed: please set both pid and mnt namesapces\n");
794                 return TEST_ERR;
795         }
796
797         if (kdbus_args->userns) {
798                 if (!config_user_ns_is_enabled()) {
799                         printf("User namespace not supported\n");
800                         return TEST_ERR;
801                 }
802
803                 if (!kdbus_args->uid_map || !kdbus_args->gid_map) {
804                         printf("Failed: please specify uid or gid mapping\n");
805                         return TEST_ERR;
806                 }
807         }
808
809         print_kdbus_test_args(kdbus_args);
810         print_metadata_support();
811
812         /* setup kdbus paths */
813         if (!kdbus_args->module)
814                 kdbus_args->module = "kdbus";
815
816         if (!kdbus_args->root) {
817                 snprintf(fspath, sizeof(fspath), "/sys/fs/%s",
818                          kdbus_args->module);
819                 kdbus_args->root = fspath;
820         }
821
822         snprintf(parampath, sizeof(parampath),
823                  "/sys/module/%s/parameters/attach_flags_mask",
824                  kdbus_args->module);
825         kdbus_args->mask_param_path = parampath;
826
827         ret = kdbus_sysfs_get_parameter_mask(kdbus_args->mask_param_path,
828                                              &kdbus_param_mask);
829         if (ret < 0)
830                 return TEST_ERR;
831
832         printf("# Starting tests with an attach_flags_mask=0x%llx\n",
833                 (unsigned long long)kdbus_param_mask);
834
835         /* Start tests */
836         if (namespaces)
837                 ret = run_tests_in_namespaces(kdbus_args);
838         else
839                 ret = run_tests(kdbus_args);
840
841         return ret;
842 }
843
844 int main(int argc, char *argv[])
845 {
846         int t, ret = 0;
847         struct kdbus_test_args *kdbus_args;
848         enum {
849                 ARG_MNTNS = 0x100,
850                 ARG_PIDNS,
851                 ARG_USERNS,
852                 ARG_UIDMAP,
853                 ARG_GIDMAP,
854         };
855         char *exec = basename(argv[0]);
856
857         kdbus_args = malloc(sizeof(*kdbus_args));
858         if (!kdbus_args) {
859                 printf("unable to malloc() kdbus_args\n");
860                 return EXIT_FAILURE;
861         }
862
863         memset(kdbus_args, 0, sizeof(*kdbus_args));
864
865         static const struct option options[] = {
866                 { "loop",       no_argument,            NULL, 'x' },
867                 { "help",       no_argument,            NULL, 'h' },
868                 { "root",       required_argument,      NULL, 'r' },
869                 { "test",       required_argument,      NULL, 't' },
870                 { "bus",        required_argument,      NULL, 'b' },
871                 { "wait",       required_argument,      NULL, 'w' },
872                 { "fork",       no_argument,            NULL, 'f' },
873                 { "module",     required_argument,      NULL, 'm' },
874                 { "tap",        no_argument,            NULL, 'a' },
875                 { "mntns",      no_argument,            NULL, ARG_MNTNS },
876                 { "pidns",      no_argument,            NULL, ARG_PIDNS },
877                 { "userns",     no_argument,            NULL, ARG_USERNS },
878                 { "uidmap",     required_argument,      NULL, ARG_UIDMAP },
879                 { "gidmap",     required_argument,      NULL, ARG_GIDMAP },
880                 {}
881         };
882
883         srand(time(NULL));
884
885         if (strcmp(exec, "kdbus-test") != 0) {
886                 kdbus_args->test = exec;
887         }
888
889         while ((t = getopt_long(argc, argv, "hxfm:r:t:b:w:a", options, NULL)) >= 0) {
890                 switch (t) {
891                 case 'x':
892                         kdbus_args->loop = 1;
893                         break;
894
895                 case 'm':
896                         kdbus_args->module = optarg;
897                         break;
898
899                 case 'r':
900                         kdbus_args->root = optarg;
901                         break;
902
903                 case 't':
904                         kdbus_args->test = optarg;
905                         break;
906
907                 case 'b':
908                         kdbus_args->busname = optarg;
909                         break;
910
911                 case 'w':
912                         kdbus_args->wait = strtol(optarg, NULL, 10);
913                         break;
914
915                 case 'f':
916                         kdbus_args->fork = 1;
917                         break;
918
919                 case 'a':
920                         kdbus_args->tap_output = 1;
921                         break;
922
923                 case ARG_MNTNS:
924                         kdbus_args->mntns = true;
925                         break;
926
927                 case ARG_PIDNS:
928                         kdbus_args->pidns = true;
929                         break;
930
931                 case ARG_USERNS:
932                         kdbus_args->userns = true;
933                         break;
934
935                 case ARG_UIDMAP:
936                         kdbus_args->uid_map = optarg;
937                         break;
938
939                 case ARG_GIDMAP:
940                         kdbus_args->gid_map = optarg;
941                         break;
942
943                 default:
944                 case 'h':
945                         usage(argv[0]);
946                 }
947         }
948
949         ret = start_tests(kdbus_args);
950         if (ret == TEST_ERR)
951                 return EXIT_FAILURE;
952
953         free(kdbus_args);
954
955         return 0;
956 }