]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-udev.c
Merge pull request #2773 from eliasp/type-warnings
[thirdparty/systemd.git] / src / test / test-udev.c
CommitLineData
1298001e
KS
1/***
2 This file is part of systemd.
3
4 Copyright 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
5 Copyright 2004-2012 Kay Sievers <kay@vrfy.org>
6
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
16
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
f0083e3d 20
c81b35c0 21#include <errno.h>
4cb72937 22#include <sched.h>
07630cea
LP
23#include <stdio.h>
24#include <stdlib.h>
4cb72937 25#include <sys/mount.h>
2181d30a 26#include <sys/signalfd.h>
07630cea 27#include <unistd.h>
85511f02 28
f4f15635 29#include "fs-util.h"
10efe2cd 30#include "missing.h"
d7b8eec7 31#include "selinux-util.h"
8314de1d 32#include "signal-util.h"
07630cea 33#include "string-util.h"
1ca208fb 34#include "udev-util.h"
07630cea 35#include "udev.h"
f0083e3d 36
4cb72937
KS
37static int fake_filesystems(void) {
38 static const struct fakefs {
39 const char *src;
40 const char *target;
41 const char *error;
42 } fakefss[] = {
43 { "test/sys", "/sys", "failed to mount test /sys" },
44 { "test/dev", "/dev", "failed to mount test /dev" },
45 { "test/run", "/run", "failed to mount test /run" },
46 { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d" },
1c2b0d55 47 { "test/run", UDEVLIBEXECDIR "/rules.d","failed to mount empty " UDEVLIBEXECDIR "/rules.d" },
4cb72937
KS
48 };
49 unsigned int i;
50 int err;
51
52 err = unshare(CLONE_NEWNS);
53 if (err < 0) {
54 err = -errno;
04eaa668
KS
55 fprintf(stderr, "failed to call unshare(): %m\n");
56 goto out;
57 }
58
59 if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
60 err = -errno;
61 fprintf(stderr, "failed to mount / as private: %m\n");
62 goto out;
4cb72937
KS
63 }
64
65 for (i = 0; i < ELEMENTSOF(fakefss); i++) {
66 err = mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL);
67 if (err < 0) {
68 err = -errno;
1c2b0d55 69 fprintf(stderr, "%s %m\n", fakefss[i].error);
4cb72937
KS
70 return err;
71 }
72 }
04eaa668 73out:
4cb72937
KS
74 return err;
75}
76
f168c273 77int main(int argc, char *argv[]) {
1ca208fb
ZJS
78 _cleanup_udev_unref_ struct udev *udev = NULL;
79 _cleanup_udev_event_unref_ struct udev_event *event = NULL;
80 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
81 _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL;
912541b0
KS
82 char syspath[UTIL_PATH_SIZE];
83 const char *devpath;
84 const char *action;
4cb72937
KS
85 int err;
86
87 err = fake_filesystems();
88 if (err < 0)
89 return EXIT_FAILURE;
912541b0
KS
90
91 udev = udev_new();
92 if (udev == NULL)
1ca208fb
ZJS
93 return EXIT_FAILURE;
94
9f6445e3 95 log_debug("version %s", VERSION);
cc56fafe 96 mac_selinux_init("/dev");
912541b0 97
912541b0
KS
98 action = argv[1];
99 if (action == NULL) {
9f6445e3 100 log_error("action missing");
912541b0
KS
101 goto out;
102 }
103
104 devpath = argv[2];
105 if (devpath == NULL) {
9f6445e3 106 log_error("devpath missing");
912541b0
KS
107 goto out;
108 }
109
110 rules = udev_rules_new(udev, 1);
111
d5a89d7d 112 strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL);
bf0e00ec 113 dev = udev_device_new_from_synthetic_event(udev, syspath, action);
912541b0 114 if (dev == NULL) {
9f6445e3 115 log_debug("unknown device '%s'", devpath);
912541b0
KS
116 goto out;
117 }
118
912541b0
KS
119 event = udev_event_new(dev);
120
72c0a2c2 121 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) >= 0);
912541b0
KS
122
123 /* do what devtmpfs usually provides us */
124 if (udev_device_get_devnode(dev) != NULL) {
83cd6b75 125 mode_t mode = 0600;
912541b0 126
090be865 127 if (streq(udev_device_get_subsystem(dev), "block"))
912541b0
KS
128 mode |= S_IFBLK;
129 else
130 mode |= S_IFCHR;
131
090be865 132 if (!streq(action, "remove")) {
d2e54fae 133 mkdir_parents_label(udev_device_get_devnode(dev), 0755);
912541b0
KS
134 mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev));
135 } else {
136 unlink(udev_device_get_devnode(dev));
37d52274 137 rmdir_parents(udev_device_get_devnode(dev), "/");
912541b0
KS
138 }
139 }
140
adeba500
KS
141 udev_event_execute_rules(event,
142 3 * USEC_PER_SEC, USEC_PER_SEC,
143 NULL,
8314de1d 144 rules);
adeba500 145 udev_event_execute_run(event,
8314de1d 146 3 * USEC_PER_SEC, USEC_PER_SEC);
2181d30a 147out:
cc56fafe 148 mac_selinux_finish();
1ca208fb
ZJS
149
150 return err ? EXIT_FAILURE : EXIT_SUCCESS;
f0083e3d 151}