]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/test/test-udev.c
util-lib: split our string related calls from util.[ch] into its own file string...
[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
10efe2cd 29#include "missing.h"
d7b8eec7 30#include "selinux-util.h"
8314de1d 31#include "signal-util.h"
07630cea 32#include "string-util.h"
1ca208fb 33#include "udev-util.h"
07630cea 34#include "udev.h"
f0083e3d 35
4cb72937
KS
36static int fake_filesystems(void) {
37 static const struct fakefs {
38 const char *src;
39 const char *target;
40 const char *error;
41 } fakefss[] = {
42 { "test/sys", "/sys", "failed to mount test /sys" },
43 { "test/dev", "/dev", "failed to mount test /dev" },
44 { "test/run", "/run", "failed to mount test /run" },
45 { "test/run", "/etc/udev/rules.d", "failed to mount empty /etc/udev/rules.d" },
46 { "test/run", "/usr/lib/udev/rules.d", "failed to mount empty /usr/lib/udev/rules.d" },
47 };
48 unsigned int i;
49 int err;
50
51 err = unshare(CLONE_NEWNS);
52 if (err < 0) {
53 err = -errno;
04eaa668
KS
54 fprintf(stderr, "failed to call unshare(): %m\n");
55 goto out;
56 }
57
58 if (mount(NULL, "/", NULL, MS_PRIVATE|MS_REC, NULL) < 0) {
59 err = -errno;
60 fprintf(stderr, "failed to mount / as private: %m\n");
61 goto out;
4cb72937
KS
62 }
63
64 for (i = 0; i < ELEMENTSOF(fakefss); i++) {
65 err = mount(fakefss[i].src, fakefss[i].target, NULL, MS_BIND, NULL);
66 if (err < 0) {
67 err = -errno;
68 fprintf(stderr, "%s %m", fakefss[i].error);
69 return err;
70 }
71 }
04eaa668 72out:
4cb72937
KS
73 return err;
74}
75
f168c273 76int main(int argc, char *argv[]) {
1ca208fb
ZJS
77 _cleanup_udev_unref_ struct udev *udev = NULL;
78 _cleanup_udev_event_unref_ struct udev_event *event = NULL;
79 _cleanup_udev_device_unref_ struct udev_device *dev = NULL;
80 _cleanup_udev_rules_unref_ struct udev_rules *rules = NULL;
912541b0
KS
81 char syspath[UTIL_PATH_SIZE];
82 const char *devpath;
83 const char *action;
4cb72937
KS
84 int err;
85
86 err = fake_filesystems();
87 if (err < 0)
88 return EXIT_FAILURE;
912541b0
KS
89
90 udev = udev_new();
91 if (udev == NULL)
1ca208fb
ZJS
92 return EXIT_FAILURE;
93
9f6445e3 94 log_debug("version %s", VERSION);
cc56fafe 95 mac_selinux_init("/dev");
912541b0 96
912541b0
KS
97 action = argv[1];
98 if (action == NULL) {
9f6445e3 99 log_error("action missing");
912541b0
KS
100 goto out;
101 }
102
103 devpath = argv[2];
104 if (devpath == NULL) {
9f6445e3 105 log_error("devpath missing");
912541b0
KS
106 goto out;
107 }
108
109 rules = udev_rules_new(udev, 1);
110
d5a89d7d 111 strscpyl(syspath, sizeof(syspath), "/sys", devpath, NULL);
bf0e00ec 112 dev = udev_device_new_from_synthetic_event(udev, syspath, action);
912541b0 113 if (dev == NULL) {
9f6445e3 114 log_debug("unknown device '%s'", devpath);
912541b0
KS
115 goto out;
116 }
117
912541b0
KS
118 event = udev_event_new(dev);
119
72c0a2c2 120 assert_se(sigprocmask_many(SIG_BLOCK, NULL, SIGTERM, SIGINT, SIGHUP, SIGCHLD, -1) >= 0);
912541b0
KS
121
122 /* do what devtmpfs usually provides us */
123 if (udev_device_get_devnode(dev) != NULL) {
83cd6b75 124 mode_t mode = 0600;
912541b0 125
090be865 126 if (streq(udev_device_get_subsystem(dev), "block"))
912541b0
KS
127 mode |= S_IFBLK;
128 else
129 mode |= S_IFCHR;
130
090be865 131 if (!streq(action, "remove")) {
d2e54fae 132 mkdir_parents_label(udev_device_get_devnode(dev), 0755);
912541b0
KS
133 mknod(udev_device_get_devnode(dev), mode, udev_device_get_devnum(dev));
134 } else {
135 unlink(udev_device_get_devnode(dev));
37d52274 136 rmdir_parents(udev_device_get_devnode(dev), "/");
912541b0
KS
137 }
138 }
139
adeba500
KS
140 udev_event_execute_rules(event,
141 3 * USEC_PER_SEC, USEC_PER_SEC,
142 NULL,
8314de1d 143 rules);
adeba500 144 udev_event_execute_run(event,
8314de1d 145 3 * USEC_PER_SEC, USEC_PER_SEC);
2181d30a 146out:
cc56fafe 147 mac_selinux_finish();
1ca208fb
ZJS
148
149 return err ? EXIT_FAILURE : EXIT_SUCCESS;
f0083e3d 150}