]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-udev.c
Merge pull request #42 from jonboulle/master
[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 <stdio.h>
f0083e3d 22#include <stdlib.h>
c81b35c0 23#include <errno.h>
1ceba936 24#include <unistd.h>
4cb72937
KS
25#include <sched.h>
26#include <sys/mount.h>
2181d30a 27#include <sys/signalfd.h>
85511f02 28
10efe2cd 29#include "missing.h"
d7b8eec7 30#include "selinux-util.h"
f0083e3d 31#include "udev.h"
1ca208fb 32#include "udev-util.h"
f0083e3d 33
4cb72937
KS
34static int fake_filesystems(void) {
35 static const struct fakefs {
36 const char *src;
37 const char *target;
38 const char *error;
39 } fakefss[] = {
40 { "test/sys", "/sys", "failed to mount test /sys" },
41 { "test/dev", "/dev", "failed to mount test /dev" },
42 { "test/run", "/run", "failed to mount test /run" },
43 { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d" },
44 { "test/run", "/usr/lib/udev/rules.d", "failed to mount empty /usr/lib/udev/rules.d" },
45 };
46 unsigned int i;
47 int err;
48
49 err = unshare(CLONE_NEWNS);
50 if (err < 0) {
51 err = -errno;
04eaa668
KS
52 fprintf(stderr, "failed to call unshare(): %m\n");
53 goto out;
54 }
55
56 if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
57 err = -errno;
58 fprintf(stderr, "failed to mount / as private: %m\n");
59 goto out;
4cb72937
KS
60 }
61
62 for (i = 0; i < ELEMENTSOF(fakefss); i++) {
63 err = mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL);
64 if (err < 0) {
65 err = -errno;
66 fprintf(stderr, "%s %m", fakefss[i].error);
67 return err;
68 }
69 }
04eaa668 70out:
4cb72937
KS
71 return err;
72}
73
f168c273 74int main(int argc, char *argv[]) {
1ca208fb
ZJS
75 _cleanup_udev_unref_ struct udev *udev = NULL;
76 _cleanup_udev_event_unref_ struct udev_event *event = NULL;
77 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
78 _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL;
912541b0
KS
79 char syspath[UTIL_PATH_SIZE];
80 const char *devpath;
81 const char *action;
82 sigset_t mask, sigmask_orig;
4cb72937
KS
83 int err;
84
85 err = fake_filesystems();
86 if (err < 0)
87 return EXIT_FAILURE;
912541b0
KS
88
89 udev = udev_new();
90 if (udev == NULL)
1ca208fb
ZJS
91 return EXIT_FAILURE;
92
9f6445e3 93 log_debug("version %s", VERSION);
cc56fafe 94 mac_selinux_init("/dev");
912541b0
KS
95
96 sigprocmask(SIG_SETMASK, NULL, &sigmask_orig);
97
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
121 sigfillset(&mask);
122 sigprocmask(SIG_SETMASK, &mask, &sigmask_orig);
912541b0
KS
123
124 /* do what devtmpfs usually provides us */
125 if (udev_device_get_devnode(dev) != NULL) {
83cd6b75 126 mode_t mode = 0600;
912541b0 127
090be865 128 if (streq(udev_device_get_subsystem(dev), "block"))
912541b0
KS
129 mode |= S_IFBLK;
130 else
131 mode |= S_IFCHR;
132
090be865 133 if (!streq(action, "remove")) {
d2e54fae 134 mkdir_parents_label(udev_device_get_devnode(dev), 0755);
912541b0
KS
135 mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev));
136 } else {
137 unlink(udev_device_get_devnode(dev));
37d52274 138 rmdir_parents(udev_device_get_devnode(dev), "/");
912541b0
KS
139 }
140 }
141
adeba500
KS
142 udev_event_execute_rules(event,
143 3 * USEC_PER_SEC, USEC_PER_SEC,
144 NULL,
145 rules,
146 &sigmask_orig);
147 udev_event_execute_run(event,
148 3 * USEC_PER_SEC, USEC_PER_SEC,
149 NULL);
2181d30a 150out:
cc56fafe 151 mac_selinux_finish();
1ca208fb
ZJS
152
153 return err ? EXIT_FAILURE : EXIT_SUCCESS;
f0083e3d 154}