diff options
author | Martin Pitt <martin.pitt@ubuntu.com> | 2015-07-08 07:08:31 +0200 |
---|---|---|
committer | Martin Pitt <martin.pitt@ubuntu.com> | 2015-07-08 07:08:31 +0200 |
commit | fb183854ab9b5774094a753ad3f46b653a9055da (patch) | |
tree | f3854bb3a4703a39aedff451b874e7cf9e53c699 /src | |
parent | 86f210e9c914ba12477d4b2e7fa6f5cfa196a324 (diff) | |
download | systemd-fb183854ab9b5774094a753ad3f46b653a9055da.tar.gz |
Imported Upstream version 222
Diffstat (limited to 'src')
230 files changed, 2342 insertions, 1216 deletions
diff --git a/src/.gitignore b/src/.gitignore new file mode 100644 index 0000000000..e6ac2d7b8a --- /dev/null +++ b/src/.gitignore @@ -0,0 +1,8 @@ +load-fragment-gperf-nulstr.c +load-fragment-gperf.c +load-fragment-gperf.gperf +org.freedesktop.systemd1.policy.in +org.freedesktop.systemd1.policy +99-systemd.rules +*.gcno +*.gcda diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000000..9d07505194 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,28 @@ +# This file is part of systemd. +# +# Copyright 2010 Lennart Poettering +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. +# +# systemd is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with systemd; If not, see <http://www.gnu.org/licenses/>. + +# This file is a dirty trick to simplify compilation from within +# emacs. This file is not intended to be distributed. So, don't touch +# it, even better ignore it! + +all: + $(MAKE) -C .. + +clean: + $(MAKE) -C .. clean + +.PHONY: all clean diff --git a/src/ac-power/Makefile b/src/ac-power/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/ac-power/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/activate/Makefile b/src/activate/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/activate/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/analyze/.gitignore b/src/analyze/.gitignore new file mode 100644 index 0000000000..752ea236c8 --- /dev/null +++ b/src/analyze/.gitignore @@ -0,0 +1 @@ +/systemd-analyze diff --git a/src/analyze/Makefile b/src/analyze/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/analyze/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/analyze/analyze.c b/src/analyze/analyze.c index 9583458f72..c0863e4167 100644 --- a/src/analyze/analyze.c +++ b/src/analyze/analyze.c @@ -1331,7 +1331,7 @@ int main(int argc, char *argv[]) { arg_user ? MANAGER_USER : MANAGER_SYSTEM, arg_man); else { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; r = bus_open_transport_systemd(arg_transport, arg_host, arg_user, &bus); if (r < 0) { diff --git a/src/ask-password/Makefile b/src/ask-password/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/ask-password/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/backlight/Makefile b/src/backlight/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/backlight/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/basic/.gitignore b/src/basic/.gitignore new file mode 100644 index 0000000000..e22411e484 --- /dev/null +++ b/src/basic/.gitignore @@ -0,0 +1,16 @@ +/cap-from-name.gperf +/cap-from-name.h +/cap-list.txt +/cap-to-name.h +/errno-from-name.gperf +/errno-from-name.h +/errno-list.txt +/errno-to-name.h +/af-from-name.gperf +/af-from-name.h +/af-list.txt +/af-to-name.h +/arphrd-from-name.gperf +/arphrd-from-name.h +/arphrd-list.txt +/arphrd-to-name.h diff --git a/src/basic/Makefile b/src/basic/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/basic/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/basic/fileio.c b/src/basic/fileio.c index ff6b1a7ed7..00fb6f8b5c 100644 --- a/src/basic/fileio.c +++ b/src/basic/fileio.c @@ -134,6 +134,17 @@ int read_one_line_file(const char *fn, char **line) { return 0; } +int verify_one_line_file(const char *fn, const char *line) { + _cleanup_free_ char *value = NULL; + int r; + + r = read_one_line_file(fn, &value); + if (r < 0) + return r; + + return streq(value, line); +} + int read_full_stream(FILE *f, char **contents, size_t *size) { size_t n, l; _cleanup_free_ char *buf = NULL; diff --git a/src/basic/fileio.h b/src/basic/fileio.h index 5ae51c1e28..91d4a0d2d5 100644 --- a/src/basic/fileio.h +++ b/src/basic/fileio.h @@ -34,6 +34,8 @@ int read_one_line_file(const char *fn, char **line); int read_full_file(const char *fn, char **contents, size_t *size); int read_full_stream(FILE *f, char **contents, size_t *size); +int verify_one_line_file(const char *fn, const char *line); + int parse_env_file(const char *fname, const char *separator, ...) _sentinel_; int load_env_file(FILE *f, const char *fname, const char *separator, char ***l); int load_env_file_pairs(FILE *f, const char *fname, const char *separator, char ***l); diff --git a/src/basic/linux/Makefile b/src/basic/linux/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/basic/linux/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/basic/path-util.c b/src/basic/path-util.c index 537705446a..8f49d65266 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -528,7 +528,7 @@ int fd_is_mount_point(int fd, const char *filename, int flags) { * * If that didn't work we will try to read the mount id from * /proc/self/fdinfo/<fd>. This is almost as good as - * name_to_handle_at(), however, does not return the the + * name_to_handle_at(), however, does not return the * opaque file handle. The opaque file handle is pretty useful * to detect the root directory, which we should always * consider a mount point. Hence we use this only as diff --git a/src/basic/process-util.c b/src/basic/process-util.c index cfc876567d..2c05f2fee4 100644 --- a/src/basic/process-util.c +++ b/src/basic/process-util.c @@ -329,6 +329,9 @@ int get_process_environ(pid_t pid, char **env) { sz += cescape_char(c, outcome + sz); } + if (sz == 0) + return -ENOENT; + outcome[sz] = '\0'; *env = outcome; outcome = NULL; diff --git a/src/basic/socket-label.c b/src/basic/socket-label.c index cbe3ff216e..144e6fd86e 100644 --- a/src/basic/socket-label.c +++ b/src/basic/socket-label.c @@ -38,6 +38,7 @@ int socket_address_listen( int backlog, SocketAddressBindIPv6Only only, const char *bind_to_device, + bool reuse_port, bool free_bind, bool transparent, mode_t directory_mode, @@ -83,6 +84,12 @@ int socket_address_listen( if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, bind_to_device, strlen(bind_to_device)+1) < 0) return -errno; + if (reuse_port) { + one = 1; + if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &one, sizeof(one)) < 0) + log_warning_errno(errno, "SO_REUSEPORT failed: %m"); + } + if (free_bind) { one = 1; if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &one, sizeof(one)) < 0) @@ -146,7 +153,7 @@ int make_socket_fd(int log_level, const char* address, int flags) { } fd = socket_address_listen(&a, flags, SOMAXCONN, SOCKET_ADDRESS_DEFAULT, - NULL, false, false, 0755, 0644, NULL); + NULL, false, false, false, 0755, 0644, NULL); if (fd < 0 || log_get_max_level() >= log_level) { _cleanup_free_ char *p = NULL; diff --git a/src/basic/socket-util.h b/src/basic/socket-util.h index 538cf59174..6b0ce7836f 100644 --- a/src/basic/socket-util.h +++ b/src/basic/socket-util.h @@ -80,6 +80,7 @@ int socket_address_listen( int backlog, SocketAddressBindIPv6Only only, const char *bind_to_device, + bool reuse_port, bool free_bind, bool transparent, mode_t directory_mode, diff --git a/src/basic/util.c b/src/basic/util.c index 727be56f58..aa912bde28 100644 --- a/src/basic/util.c +++ b/src/basic/util.c @@ -3627,7 +3627,7 @@ bool string_is_safe(const char *p) { if (*t > 0 && *t < ' ') return false; - if (strchr("\\\"\'\0x7f", *t)) + if (strchr("\\\"\'\x7f", *t)) return false; } @@ -5925,10 +5925,9 @@ int rename_noreplace(int olddirfd, const char *oldpath, int newdirfd, const char if (ret >= 0) return 0; - /* Even though renameat2() exists since Linux 3.15, btrfs added - * support for it later. If it is not implemented, fallback to another - * method. */ - if (errno != EINVAL) + /* renameat2() exists since Linux 3.15, btrfs added support for it later. + * If it is not implemented, fallback to another method. */ + if (!IN_SET(errno, EINVAL, ENOSYS)) return -errno; /* The link()/unlink() fallback does not work on directories. But diff --git a/src/binfmt/Makefile b/src/binfmt/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/binfmt/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/boot/Makefile b/src/boot/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/boot/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c index 1e65597acf..ed69fb0cec 100644 --- a/src/boot/bootctl.c +++ b/src/boot/bootctl.c @@ -918,7 +918,7 @@ static int install_loader_config(const char *esp_path) { static int help(void) { printf("%s [COMMAND] [OPTIONS...]\n" "\n" - "Install, update or remove the sdboot EFI boot manager.\n\n" + "Install, update or remove the systemd-boot EFI boot manager.\n\n" " -h --help Show this help\n" " --version Print version\n" " --path=PATH Path to the EFI System Partition (ESP)\n" diff --git a/src/boot/efi/.gitignore b/src/boot/efi/.gitignore new file mode 100644 index 0000000000..e193acbe12 --- /dev/null +++ b/src/boot/efi/.gitignore @@ -0,0 +1,2 @@ +/systemd_boot.so +/stub.so diff --git a/src/bootchart/Makefile b/src/bootchart/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/bootchart/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/bootchart/store.c b/src/bootchart/store.c index f159cbafe2..caa97b97fc 100644 --- a/src/bootchart/store.c +++ b/src/bootchart/store.c @@ -37,6 +37,7 @@ #include "store.h" #include "bootchart.h" #include "cgroup-util.h" +#include "fileio.h" /* * Alloc a static 4k buffer for stdio - primarily used to increase @@ -97,13 +98,14 @@ int log_sample(DIR *proc, int *cpus) { static int vmstat = -1; - static int schedstat = -1; + _cleanup_free_ char *buf_schedstat = NULL; char buf[4096]; char key[256]; char val[256]; char rt[256]; char wt[256]; char *m; + int r; int c; int p; int mod; @@ -115,6 +117,7 @@ int log_sample(DIR *proc, struct list_sample_data *sampledata; struct ps_sched_struct *ps_prev = NULL; int procfd; + int taskfd = -1; sampledata = *ptr; @@ -155,27 +158,13 @@ vmstat_next: break; } - if (schedstat < 0) { - /* overall CPU utilization */ - schedstat = openat(procfd, "schedstat", O_RDONLY|O_CLOEXEC); - if (schedstat < 0) - return log_error_errno(errno, "Failed to open /proc/schedstat (requires CONFIG_SCHEDSTATS=y in kernel config): %m"); - } - - n = pread(schedstat, buf, sizeof(buf) - 1, 0); - if (n <= 0) { - schedstat = safe_close(schedstat); - if (n < 0) - return -errno; - return -ENODATA; - } + /* Parse "/proc/schedstat" for overall CPU utilization */ + r = read_full_file("/proc/schedstat", &buf_schedstat, NULL); + if (r < 0) + return log_error_errno(r, "Unable to read schedstat: %m"); - buf[n] = '\0'; - - m = buf; + m = buf_schedstat; while (m) { - int r; - if (sscanf(m, "%s %*s %*s %*s %*s %*s %*s %s %s", key, rt, wt) < 3) goto schedstat_next; @@ -237,7 +226,6 @@ schedstat_next: _cleanup_fclose_ FILE *st = NULL; char t[32]; struct ps_struct *parent; - int r; ps->next_ps = new0(struct ps_struct, 1); if (!ps->next_ps) @@ -409,6 +397,62 @@ schedstat_next: ps->total = (ps->last->runtime - ps->first->runtime) / 1000000000.0; + /* Take into account CPU runtime/waittime spent in non-main threads of the process + * by parsing "/proc/[pid]/task/[tid]/schedstat" for all [tid] != [pid] + * See https://github.com/systemd/systemd/issues/139 + */ + + /* Browse directory "/proc/[pid]/task" to know the thread ids of process [pid] */ + snprintf(filename, sizeof(filename), PID_FMT "/task", pid); + taskfd = openat(procfd, filename, O_RDONLY|O_DIRECTORY|O_CLOEXEC); + if (taskfd >= 0) { + _cleanup_closedir_ DIR *taskdir = NULL; + + taskdir = fdopendir(taskfd); + if (!taskdir) { + safe_close(taskfd); + return -errno; + } + FOREACH_DIRENT(ent, taskdir, break) { + int tid = -1; + _cleanup_close_ int tid_schedstat = -1; + long long delta_rt; + long long delta_wt; + + if ((ent->d_name[0] < '0') || (ent->d_name[0] > '9')) + continue; + + /* Skip main thread as it was already accounted */ + r = safe_atoi(ent->d_name, &tid); + if (r < 0 || tid == pid) + continue; + + /* Parse "/proc/[pid]/task/[tid]/schedstat" */ + snprintf(filename, sizeof(filename), PID_FMT "/schedstat", tid); + tid_schedstat = openat(taskfd, filename, O_RDONLY|O_CLOEXEC); + + if (tid_schedstat == -1) + continue; + + s = pread(tid_schedstat, buf, sizeof(buf) - 1, 0); + if (s <= 0) + continue; + buf[s] = '\0'; + + if (!sscanf(buf, "%s %s %*s", rt, wt)) + continue; + + r = safe_atolli(rt, &delta_rt); + if (r < 0) + continue; + r = safe_atolli(rt, &delta_wt); + if (r < 0) + continue; + ps->sample->runtime += delta_rt; + ps->sample->waittime += delta_wt; + } + } + if (!arg_pss) goto catch_rename; diff --git a/src/bootchart/svg.c b/src/bootchart/svg.c index 0132475e10..a7ef653d5d 100644 --- a/src/bootchart/svg.c +++ b/src/bootchart/svg.c @@ -69,15 +69,13 @@ static double esize = 0; static struct list_sample_data *sampledata; static struct list_sample_data *prev_sampledata; -static void svg_header(FILE *of, struct list_sample_data *head, double graph_start) { +static void svg_header(FILE *of, struct list_sample_data *head, double graph_start, int n_cpus) { double w; double h; struct list_sample_data *sampledata_last; assert(head); - sampledata = head; - LIST_FIND_TAIL(link, sampledata, head); sampledata_last = head; LIST_FOREACH_BEFORE(link, sampledata, head) { sampledata_last = sampledata; @@ -90,7 +88,7 @@ static void svg_header(FILE *of, struct list_sample_data *head, double graph_sta /* height is variable based on pss, psize, ksize */ h = 400.0 + (arg_scale_y * 30.0) /* base graphs and title */ + (arg_pss ? (100.0 * arg_scale_y) + (arg_scale_y * 7.0) : 0.0) /* pss estimate */ - + psize + ksize + esize; + + psize + ksize + esize + (n_cpus * 15 * arg_scale_y); fprintf(of, "<?xml version=\"1.0\" standalone=\"no\"?>\n"); fprintf(of, "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" "); @@ -174,7 +172,7 @@ static int svg_title(FILE *of, const char *build, int pscount, double log_start, r = read_one_line_file(filename, &model); if (r < 0) - log_warning("Error reading disk model for %s: %m\n", rootbdev); + log_info("Error reading disk model for %s: %m\n", rootbdev); } /* various utsname parameters */ @@ -210,7 +208,8 @@ static int svg_title(FILE *of, const char *build, int pscount, double log_start, fprintf(of, "<text class=\"t2\" x=\"20\" y=\"50\">System: %s %s %s %s</text>\n", uts.sysname, uts.release, uts.version, uts.machine); fprintf(of, "<text class=\"t2\" x=\"20\" y=\"65\">CPU: %s</text>\n", cpu); - fprintf(of, "<text class=\"t2\" x=\"20\" y=\"80\">Disk: %s</text>\n", model); + if (model) + fprintf(of, "<text class=\"t2\" x=\"20\" y=\"80\">Disk: %s</text>\n", model); fprintf(of, "<text class=\"t2\" x=\"20\" y=\"95\">Boot options: %s</text>\n", cmdline); fprintf(of, "<text class=\"t2\" x=\"20\" y=\"110\">Build: %s</text>\n", build); fprintf(of, "<text class=\"t2\" x=\"20\" y=\"125\">Log start time: %.03fs</text>\n", log_start); @@ -1296,6 +1295,8 @@ int svg_do(FILE *of, double offset = 7; int r, c; + sampledata = head; + LIST_FIND_TAIL(link, sampledata, head); ps = ps_first; /* count initcall thread count first */ @@ -1314,7 +1315,7 @@ int svg_do(FILE *of, esize = (arg_entropy ? arg_scale_y * 7 : 0); /* after this, we can draw the header with proper sizing */ - svg_header(of, head, graph_start); + svg_header(of, head, graph_start, arg_percpu ? n_cpus : 0); fprintf(of, "<rect class=\"bg\" width=\"100%%\" height=\"100%%\" />\n\n"); fprintf(of, "<g transform=\"translate(10,400)\">\n"); diff --git a/src/bus-proxyd/Makefile b/src/bus-proxyd/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/bus-proxyd/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/bus-proxyd/bus-xml-policy.c b/src/bus-proxyd/bus-xml-policy.c index 675d24485e..dab5acbcb4 100644 --- a/src/bus-proxyd/bus-xml-policy.c +++ b/src/bus-proxyd/bus-xml-policy.c @@ -301,7 +301,7 @@ static int file_load(Policy *p, const char *path) { ic = POLICY_ITEM_USER; else if (streq(name, "group")) ic = POLICY_ITEM_GROUP; - else if (streq(name, "eavesdrop")) { + else if (STR_IN_SET(name, "eavesdrop", "log")) { log_debug("Unsupported attribute %s= at %s:%u, ignoring.", name, path, line); state = STATE_ALLOW_DENY_OTHER_ATTRIBUTE; break; diff --git a/src/bus-proxyd/proxy.c b/src/bus-proxyd/proxy.c index 28ab1c97fc..189ee969c7 100644 --- a/src/bus-proxyd/proxy.c +++ b/src/bus-proxyd/proxy.c @@ -45,7 +45,7 @@ #include "formats-util.h" static int proxy_create_destination(Proxy *p, const char *destination, const char *local_sec, bool negotiate_fds) { - _cleanup_bus_close_unref_ sd_bus *b = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; int r; r = sd_bus_new(&b); @@ -101,7 +101,7 @@ static int proxy_create_destination(Proxy *p, const char *destination, const cha } static int proxy_create_local(Proxy *p, int in_fd, int out_fd, bool negotiate_fds) { - _cleanup_bus_close_unref_ sd_bus *b = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; sd_id128_t server_id; int r; @@ -144,6 +144,10 @@ static int proxy_create_local(Proxy *p, int in_fd, int out_fd, bool negotiate_fd return 0; } +/* + * dbus-1 clients receive NameOwnerChanged and directed signals without + * subscribing to them; install the matches to receive them on kdbus. + */ static int proxy_prepare_matches(Proxy *p) { _cleanup_free_ char *match = NULL; const char *unique; @@ -189,6 +193,20 @@ static int proxy_prepare_matches(Proxy *p) { if (r < 0) return log_error_errno(r, "Failed to add match for NameAcquired: %m"); + free(match); + match = strjoin("type='signal'," + "destination='", + unique, + "'", + NULL); + if (!match) + return log_oom(); + + r = sd_bus_add_match(p->destination_bus, NULL, match, NULL, NULL); + if (r < 0) + log_error_errno(r, "Failed to add match for directed signals: %m"); + /* FIXME: temporarily ignore error to support older kdbus versions */ + return 0; } @@ -238,8 +256,8 @@ Proxy *proxy_free(Proxy *p) { if (!p) return NULL; - sd_bus_close_unrefp(&p->local_bus); - sd_bus_close_unrefp(&p->destination_bus); + sd_bus_flush_close_unref(p->local_bus); + sd_bus_flush_close_unref(p->destination_bus); set_free_free(p->owned_names); free(p); @@ -494,7 +512,16 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m, } /* First check if we (the sender) can send to this name */ - if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, destination_names, m->path, m->interface, m->member, true, &n)) { + if (sd_bus_message_is_signal(m, NULL, NULL)) { + /* If we forward a signal from dbus-1 to kdbus, we have + * no idea who the recipient is. Therefore, we cannot + * apply any dbus-1 policies that match on receiver + * credentials. We know sd-bus always sets + * KDBUS_MSG_SIGNAL, so the kernel applies policies to + * the message. Therefore, skip policy checks in this + * case. */ + return 0; + } else if (policy_check_send(policy, our_ucred->uid, our_ucred->gid, m->header->type, NULL, destination_names, m->path, m->interface, m->member, true, &n)) { if (n) { /* If we made a receiver decision, then remember which * name's policy we used, and to which unique ID it @@ -512,19 +539,8 @@ static int process_policy_unlocked(sd_bus *from, sd_bus *to, sd_bus_message *m, return r; } - if (sd_bus_message_is_signal(m, NULL, NULL)) { - /* If we forward a signal from dbus-1 to kdbus, - * we have no idea who the recipient is. - * Therefore, we cannot apply any dbus-1 - * receiver policies that match on receiver - * credentials. We know sd-bus always sets - * KDBUS_MSG_SIGNAL, so the kernel applies - * receiver policies to the message. Therefore, - * skip policy checks in this case. */ - return 0; - } else if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, owned_names, NULL, m->path, m->interface, m->member, true)) { + if (policy_check_recv(policy, destination_uid, destination_gid, m->header->type, owned_names, NULL, m->path, m->interface, m->member, true)) return 0; - } } /* Return an error back to the caller */ diff --git a/src/cgls/Makefile b/src/cgls/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/cgls/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/cgls/cgls.c b/src/cgls/cgls.c index c6f5485716..46a444340a 100644 --- a/src/cgls/cgls.c +++ b/src/cgls/cgls.c @@ -127,7 +127,7 @@ int main(int argc, char *argv[]) { int r = 0, retval = EXIT_FAILURE; int output_flags; _cleanup_free_ char *root = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; log_parse_environment(); log_open(); diff --git a/src/cgroups-agent/Makefile b/src/cgroups-agent/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/cgroups-agent/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/cgroups-agent/cgroups-agent.c b/src/cgroups-agent/cgroups-agent.c index 529e843030..612bc8fdec 100644 --- a/src/cgroups-agent/cgroups-agent.c +++ b/src/cgroups-agent/cgroups-agent.c @@ -26,7 +26,7 @@ #include "bus-util.h" int main(int argc, char *argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; if (argc != 2) { diff --git a/src/cgtop/Makefile b/src/cgtop/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/cgtop/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/compat-libs/.gitignore b/src/compat-libs/.gitignore new file mode 100644 index 0000000000..662c154cdd --- /dev/null +++ b/src/compat-libs/.gitignore @@ -0,0 +1 @@ +/libsystemd-*.pc diff --git a/src/console/Makefile b/src/console/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/console/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/core/.gitignore b/src/core/.gitignore new file mode 100644 index 0000000000..f293bbdc93 --- /dev/null +++ b/src/core/.gitignore @@ -0,0 +1,2 @@ +/macros.systemd +/systemd.pc diff --git a/src/core/Makefile b/src/core/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/core/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/core/dbus.c b/src/core/dbus.c index 86886e6d2c..057653a8b5 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -69,13 +69,37 @@ int bus_send_queued_message(Manager *m) { } static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL; + const char *cgroup, *me; Manager *m = userdata; - const char *cgroup; + uid_t sender_uid; + sd_bus *bus; int r; assert(message); assert(m); + /* ignore recursive events sent by us on the system/user bus */ + bus = sd_bus_message_get_bus(message); + if (!sd_bus_is_server(bus)) { + r = sd_bus_get_unique_name(bus, &me); + if (r < 0) + return r; + + if (streq_ptr(sd_bus_message_get_sender(message), me)) + return 0; + } + + /* only accept org.freedesktop.systemd1.Agent from UID=0 */ + r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_EUID, &creds); + if (r < 0) + return r; + + r = sd_bus_creds_get_euid(creds, &sender_uid); + if (r < 0 || sender_uid != 0) + return 0; + + /* parse 'cgroup-empty' notification */ r = sd_bus_message_read(message, "s", &cgroup); if (r < 0) { bus_log_parse_error(r); @@ -84,19 +108,15 @@ static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus manager_notify_cgroup_empty(m, cgroup); - /* only forward to system bus if running as system instance */ - if (m->running_as != MANAGER_SYSTEM || !m->system_bus) - return 0; - - r = sd_bus_message_rewind(message, 1); - if (r < 0) - goto exit; - - r = sd_bus_send(m->system_bus, message, NULL); + /* if running as system-instance, forward under our name */ + if (m->running_as == MANAGER_SYSTEM && m->system_bus) { + r = sd_bus_message_rewind(message, 1); + if (r >= 0) + r = sd_bus_send(m->system_bus, message, NULL); + if (r < 0) + log_warning_errno(r, "Failed to forward Released message: %m"); + } -exit: - if (r < 0) - log_warning_errno(r, "Failed to forward Released message: %m"); return 0; } diff --git a/src/core/execute.c b/src/core/execute.c index 94cc101738..c92db51330 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -1717,6 +1717,15 @@ static int exec_child( return r; } } +#ifdef SMACK_DEFAULT_PROCESS_LABEL + else { + r = mac_smack_apply_pid(0, SMACK_DEFAULT_PROCESS_LABEL); + if (r < 0) { + *exit_status = EXIT_SMACK_PROCESS_LABEL; + return r; + } + } +#endif #endif if (context->user) { diff --git a/src/core/job.c b/src/core/job.c index 8a047df0c3..1448e5b69a 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -452,7 +452,7 @@ static bool job_is_runnable(Job *j) { j->type == JOB_RELOAD) { /* Immediate result is that the job is or might be - * started. In this case lets wait for the + * started. In this case let's wait for the * dependencies, regardless whether they are * starting or stopping something. */ @@ -462,7 +462,7 @@ static bool job_is_runnable(Job *j) { } /* Also, if something else is being stopped and we should - * change state after it, then lets wait. */ + * change state after it, then let's wait. */ SET_FOREACH(other, j->unit->dependencies[UNIT_BEFORE], i) if (other->job && diff --git a/src/core/kmod-setup.c b/src/core/kmod-setup.c index e7a6bdc8c4..fc6d2f4acb 100644 --- a/src/core/kmod-setup.c +++ b/src/core/kmod-setup.c @@ -116,7 +116,7 @@ int kmod_setup(void) { else if (r == KMOD_PROBE_APPLY_BLACKLIST) log_info("Module '%s' is blacklisted", kmod_module_get_name(mod)); else { - bool print_warning = kmod_table[i].warn_if_unavailable || (r < 0 && r != -ENOSYS); + bool print_warning = kmod_table[i].warn_if_unavailable || (r < 0 && r != -ENOENT); log_full_errno(print_warning ? LOG_WARNING : LOG_DEBUG, r, "Failed to insert module '%s': %m", kmod_module_get_name(mod)); diff --git a/src/core/main.c b/src/core/main.c index 332453a0ea..523f0ce020 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1995,6 +1995,10 @@ finish: command_line[pos++] = "kmsg"; break; + case LOG_TARGET_NULL: + command_line[pos++] = "null"; + break; + case LOG_TARGET_CONSOLE: default: command_line[pos++] = "console"; diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c index 42a6b952b9..1782d40720 100644 --- a/src/core/mount-setup.c +++ b/src/core/mount-setup.c @@ -27,6 +27,7 @@ #include "mount-setup.h" #include "dev-setup.h" +#include "bus-util.h" #include "log.h" #include "macro.h" #include "util.h" @@ -105,7 +106,7 @@ static const MountPoint mount_table[] = { is_efi_boot, MNT_NONE }, #endif { "kdbusfs", "/sys/fs/kdbus", "kdbusfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, - NULL, MNT_IN_CONTAINER }, + is_kdbus_wanted, MNT_IN_CONTAINER }, }; /* These are API file systems that might be mounted by other software, diff --git a/src/core/service.c b/src/core/service.c index fa1e80b710..d72ff54daa 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -1235,7 +1235,7 @@ static int main_pid_good(Service *s) { /* Returns 0 if the pid is dead, 1 if it is good, -1 if we * don't know */ - /* If we know the pid file, then lets just check if it is + /* If we know the pid file, then let's just check if it is * still valid */ if (s->main_pid_known) { diff --git a/src/core/smack-setup.c b/src/core/smack-setup.c index ff2a02004d..ddb02a1580 100644 --- a/src/core/smack-setup.c +++ b/src/core/smack-setup.c @@ -34,31 +34,35 @@ #include "fileio.h" #include "log.h" -#define SMACK_CONFIG "/etc/smack/accesses.d/" -#define CIPSO_CONFIG "/etc/smack/cipso.d/" - #ifdef HAVE_SMACK -static int write_rules(const char* dstpath, const char* srcdir) { - _cleanup_fclose_ FILE *dst = NULL; +static int write_access2_rules(const char* srcdir) { + _cleanup_close_ int load2_fd = -1, change_fd = -1; _cleanup_closedir_ DIR *dir = NULL; struct dirent *entry; char buf[NAME_MAX]; int dfd = -1; int r = 0; - dst = fopen(dstpath, "we"); - if (!dst) { + load2_fd = open("/sys/fs/smackfs/load2", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (load2_fd < 0) { + if (errno != ENOENT) + log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/load2': %m"); + return -errno; /* negative error */ + } + + change_fd = open("/sys/fs/smackfs/change-rule", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (change_fd < 0) { if (errno != ENOENT) - log_warning_errno(errno, "Failed to open %s: %m", dstpath); + log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/change-rule': %m"); return -errno; /* negative error */ } - /* write rules to dst from every file in the directory */ + /* write rules to load2 or change-rule from every file in the directory */ dir = opendir(srcdir); if (!dir) { if (errno != ENOENT) - log_warning_errno(errno, "Failed to opendir %s: %m", srcdir); + log_warning_errno(errno, "Failed to opendir '%s': %m", srcdir); return errno; /* positive on purpose */ } @@ -69,11 +73,14 @@ static int write_rules(const char* dstpath, const char* srcdir) { int fd; _cleanup_fclose_ FILE *policy = NULL; + if (!dirent_is_file(entry)) + continue; + fd = openat(dfd, entry->d_name, O_RDONLY|O_CLOEXEC); if (fd < 0) { if (r == 0) r = -errno; - log_warning_errno(errno, "Failed to open %s: %m", entry->d_name); + log_warning_errno(errno, "Failed to open '%s': %m", entry->d_name); continue; } @@ -82,30 +89,108 @@ static int write_rules(const char* dstpath, const char* srcdir) { if (r == 0) r = -errno; safe_close(fd); - log_error_errno(errno, "Failed to open %s: %m", entry->d_name); + log_error_errno(errno, "Failed to open '%s': %m", entry->d_name); continue; } /* load2 write rules in the kernel require a line buffered stream */ FOREACH_LINE(buf, policy, - log_error_errno(errno, "Failed to read line from %s: %m", - entry->d_name)) { - if (!fputs(buf, dst)) { + log_error_errno(errno, "Failed to read line from '%s': %m", + entry->d_name)) { + + _cleanup_free_ char *sbj = NULL, *obj = NULL, *acc1 = NULL, *acc2 = NULL; + + if (isempty(truncate_nl(buf))) + continue; + + /* if 3 args -> load rule : subject object access1 */ + /* if 4 args -> change rule : subject object access1 access2 */ + if (sscanf(buf, "%ms %ms %ms %ms", &sbj, &obj, &acc1, &acc2) < 3) { + log_error_errno(errno, "Failed to parse rule '%s' in '%s', ignoring.", buf, entry->d_name); + continue; + } + + if (write(isempty(acc2) ? load2_fd : change_fd, buf, strlen(buf)) < 0) { if (r == 0) - r = -EINVAL; - log_error("Failed to write line to %s", dstpath); - break; + r = -errno; + log_error_errno(errno, "Failed to write '%s' to '%s' in '%s'", + buf, isempty(acc2) ? "/sys/fs/smackfs/load2" : "/sys/fs/smackfs/change-rule", entry->d_name); } - if (fflush(dst)) { + } + } + + return r; +} + +static int write_cipso2_rules(const char* srcdir) { + _cleanup_close_ int cipso2_fd = -1; + _cleanup_closedir_ DIR *dir = NULL; + struct dirent *entry; + char buf[NAME_MAX]; + int dfd = -1; + int r = 0; + + cipso2_fd = open("/sys/fs/smackfs/cipso2", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + if (cipso2_fd < 0) { + if (errno != ENOENT) + log_warning_errno(errno, "Failed to open '/sys/fs/smackfs/cipso2': %m"); + return -errno; /* negative error */ + } + + /* write rules to cipso2 from every file in the directory */ + dir = opendir(srcdir); + if (!dir) { + if (errno != ENOENT) + log_warning_errno(errno, "Failed to opendir '%s': %m", srcdir); + return errno; /* positive on purpose */ + } + + dfd = dirfd(dir); + assert(dfd >= 0); + + FOREACH_DIRENT(entry, dir, return 0) { + int fd; + _cleanup_fclose_ FILE *policy = NULL; + + if (!dirent_is_file(entry)) + continue; + + fd = openat(dfd, entry->d_name, O_RDONLY|O_CLOEXEC); + if (fd < 0) { + if (r == 0) + r = -errno; + log_error_errno(errno, "Failed to open '%s': %m", entry->d_name); + continue; + } + + policy = fdopen(fd, "re"); + if (!policy) { + if (r == 0) + r = -errno; + safe_close(fd); + log_error_errno(errno, "Failed to open '%s': %m", entry->d_name); + continue; + } + + /* cipso2 write rules in the kernel require a line buffered stream */ + FOREACH_LINE(buf, policy, + log_error_errno(errno, "Failed to read line from '%s': %m", + entry->d_name)) { + + if (isempty(truncate_nl(buf))) + continue; + + if (write(cipso2_fd, buf, strlen(buf)) < 0) { if (r == 0) r = -errno; - log_error_errno(errno, "Failed to flush writes to %s: %m", dstpath); + log_error_errno(errno, "Failed to write '%s' to '/sys/fs/smackfs/cipso2' in '%s'", + buf, entry->d_name); break; } } } - return r; + return r; } #endif @@ -118,13 +203,13 @@ int mac_smack_setup(bool *loaded_policy) { assert(loaded_policy); - r = write_rules("/sys/fs/smackfs/load2", SMACK_CONFIG); + r = write_access2_rules("/etc/smack/accesses.d/"); switch(r) { case -ENOENT: log_debug("Smack is not enabled in the kernel."); return 0; case ENOENT: - log_debug("Smack access rules directory " SMACK_CONFIG " not found"); + log_debug("Smack access rules directory '/etc/smack/accesses.d/' not found"); return 0; case 0: log_info("Successfully loaded Smack policies."); @@ -142,13 +227,13 @@ int mac_smack_setup(bool *loaded_policy) { SMACK_RUN_LABEL, strerror(-r)); #endif - r = write_rules("/sys/fs/smackfs/cipso2", CIPSO_CONFIG); + r = write_cipso2_rules("/etc/smack/cipso.d/"); switch(r) { case -ENOENT: log_debug("Smack/CIPSO is not enabled in the kernel."); return 0; case ENOENT: - log_debug("Smack/CIPSO access rules directory " CIPSO_CONFIG " not found"); + log_debug("Smack/CIPSO access rules directory '/etc/smack/cipso.d/' not found"); return 0; case 0: log_info("Successfully loaded Smack/CIPSO policies."); diff --git a/src/core/socket.c b/src/core/socket.c index d3178e642b..693cbc6080 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -922,12 +922,6 @@ static void socket_apply_socket_options(Socket *s, int fd) { if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0) log_unit_warning_errno(UNIT(s), errno, "TCP_CONGESTION failed: %m"); - if (s->reuse_port) { - int b = s->reuse_port; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &b, sizeof(b)) < 0) - log_unit_warning_errno(UNIT(s), errno, "SO_REUSEPORT failed: %m"); - } - if (s->smack_ip_in) { r = mac_smack_apply_ip_in_fd(fd, s->smack_ip_in); if (r < 0) @@ -1183,6 +1177,7 @@ static int socket_open_fds(Socket *s) { s->backlog, s->bind_ipv6_only, s->bind_to_device, + s->reuse_port, s->free_bind, s->transparent, s->directory_mode, diff --git a/src/core/unit.c b/src/core/unit.c index 7bb2afc9f2..fac017c57d 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1596,7 +1596,7 @@ static void unit_check_unneeded(Unit *u) { static const UnitDependency needed_dependencies[] = { UNIT_REQUIRED_BY, UNIT_REQUIRED_BY_OVERRIDABLE, - UNIT_REQUISITE, + UNIT_REQUISITE_OF, UNIT_REQUISITE_OF_OVERRIDABLE, UNIT_WANTED_BY, UNIT_BOUND_BY, diff --git a/src/cryptsetup/Makefile b/src/cryptsetup/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/cryptsetup/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/dbus1-generator/Makefile b/src/dbus1-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/dbus1-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/debug-generator/Makefile b/src/debug-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/debug-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/delta/Makefile b/src/delta/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/delta/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/detect-virt/Makefile b/src/detect-virt/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/detect-virt/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/efi-boot-generator/Makefile b/src/efi-boot-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/efi-boot-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/escape/Makefile b/src/escape/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/escape/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/escape/escape.c b/src/escape/escape.c index 9ccb015538..341453398d 100644 --- a/src/escape/escape.c +++ b/src/escape/escape.c @@ -236,5 +236,5 @@ int main(int argc, char *argv[]) { fputc('\n', stdout); finish: - return r <= 0 ? EXIT_FAILURE : EXIT_SUCCESS; + return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; } diff --git a/src/firstboot/Makefile b/src/firstboot/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/firstboot/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/fsck/Makefile b/src/fsck/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/fsck/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/fsck/fsck.c b/src/fsck/fsck.c index 30254b6680..bd3051f30d 100644 --- a/src/fsck/fsck.c +++ b/src/fsck/fsck.c @@ -62,7 +62,7 @@ static const char *arg_repair = "-a"; static void start_target(const char *target) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; assert(target); diff --git a/src/fstab-generator/Makefile b/src/fstab-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/fstab-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/getty-generator/Makefile b/src/getty-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/getty-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/gpt-auto-generator/Makefile b/src/gpt-auto-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/gpt-auto-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/hibernate-resume/Makefile b/src/hibernate-resume/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/hibernate-resume/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/hostname/.gitignore b/src/hostname/.gitignore new file mode 100644 index 0000000000..1ff281b231 --- /dev/null +++ b/src/hostname/.gitignore @@ -0,0 +1 @@ +org.freedesktop.hostname1.policy diff --git a/src/hostname/Makefile b/src/hostname/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/hostname/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/hostname/hostnamectl.c b/src/hostname/hostnamectl.c index 69ecd61f60..c996fc04a0 100644 --- a/src/hostname/hostnamectl.c +++ b/src/hostname/hostnamectl.c @@ -509,7 +509,7 @@ static int hostnamectl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char *argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index 7ff3a4e224..e52b872a8c 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -663,7 +663,7 @@ static const sd_bus_vtable hostname_vtable[] = { }; static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; assert(c); @@ -695,7 +695,7 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { int main(int argc, char *argv[]) { Context context = {}; _cleanup_event_unref_ sd_event *event = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; log_set_target(LOG_TARGET_AUTO); diff --git a/src/hwdb/Makefile b/src/hwdb/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/hwdb/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/import/.gitignore b/src/import/.gitignore new file mode 100644 index 0000000000..01106e2e68 --- /dev/null +++ b/src/import/.gitignore @@ -0,0 +1 @@ +/org.freedesktop.import1.policy diff --git a/src/import/Makefile b/src/import/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/import/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/import/importd.c b/src/import/importd.c index 03aede6016..dd314f5b00 100644 --- a/src/import/importd.c +++ b/src/import/importd.c @@ -551,8 +551,7 @@ static Manager *manager_unref(Manager *m) { bus_verify_polkit_async_registry_free(m->polkit_registry); - sd_bus_close(m->bus); - sd_bus_unref(m->bus); + m->bus = sd_bus_flush_close_unref(m->bus); sd_event_unref(m->event); free(m); diff --git a/src/initctl/Makefile b/src/initctl/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/initctl/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/journal-remote/.gitignore b/src/journal-remote/.gitignore new file mode 100644 index 0000000000..06847b65d4 --- /dev/null +++ b/src/journal-remote/.gitignore @@ -0,0 +1,2 @@ +/journal-remote.conf +/journal-upload.conf diff --git a/src/journal-remote/Makefile b/src/journal-remote/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/journal-remote/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/journal-remote/log-generator.py b/src/journal-remote/log-generator.py new file mode 100755 index 0000000000..9a8fb07c7f --- /dev/null +++ b/src/journal-remote/log-generator.py @@ -0,0 +1,68 @@ +#!/usr/bin/python +from __future__ import print_function +import sys +import argparse + +PARSER = argparse.ArgumentParser() +PARSER.add_argument('n', type=int) +PARSER.add_argument('--dots', action='store_true') +OPTIONS = PARSER.parse_args() + +template = """\ +__CURSOR=s=6863c726210b4560b7048889d8ada5c5;i=3e931;b=f446871715504074bf7049ef0718fa93;m={m:x};t=4fd05c +__REALTIME_TIMESTAMP={realtime_ts} +__MONOTONIC_TIMESTAMP={monotonic_ts} +_BOOT_ID=f446871715504074bf7049ef0718fa93 +_TRANSPORT=syslog +PRIORITY={priority} +SYSLOG_FACILITY={facility} +SYSLOG_IDENTIFIER=/USR/SBIN/CRON +MESSAGE={message} +_UID=0 +_GID=0 +_MACHINE_ID=69121ca41d12c1b69a7960174c27b618 +_HOSTNAME=hostname +SYSLOG_PID=25721 +_PID=25721 +_SOURCE_REALTIME_TIMESTAMP={source_realtime_ts} +DATA={data} +""" + +m = 0x198603b12d7 +realtime_ts = 1404101101501873 +monotonic_ts = 1753961140951 +source_realtime_ts = 1404101101483516 +priority = 3 +facility = 6 + +src = open('/dev/urandom', 'rb') + +bytes = 0 + +for i in range(OPTIONS.n): + message = repr(src.read(2000)) + data = repr(src.read(4000)) + + entry = template.format(m=m, + realtime_ts=realtime_ts, + monotonic_ts=monotonic_ts, + source_realtime_ts=source_realtime_ts, + priority=priority, + facility=facility, + message=message, + data=data) + m += 1 + realtime_ts += 1 + monotonic_ts += 1 + source_realtime_ts += 1 + + bytes += len(entry) + + print(entry) + + if OPTIONS.dots: + print('.', file=sys.stderr, end='', flush=True) + +if OPTIONS.dots: + print(file=sys.stderr) +print('Wrote {} bytes'.format(bytes), file=sys.stderr) diff --git a/src/journal/.gitignore b/src/journal/.gitignore new file mode 100644 index 0000000000..04d5852547 --- /dev/null +++ b/src/journal/.gitignore @@ -0,0 +1,4 @@ +/journald-gperf.c +/libsystemd-journal.pc +/audit_type-list.txt +/audit_type-*-name.* diff --git a/src/journal/Makefile b/src/journal/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/journal/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/journal/journalctl.c b/src/journal/journalctl.c index 76ec0827e7..2d6ecfb750 100644 --- a/src/journal/journalctl.c +++ b/src/journal/journalctl.c @@ -1719,7 +1719,7 @@ static int access_check(sd_journal *j) { static int flush_to_var(void) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; _cleanup_close_ int watch_fd = -1; int r; diff --git a/src/journal/journald-server.c b/src/journal/journald-server.c index f7402984af..46358e1c1a 100644 --- a/src/journal/journald-server.c +++ b/src/journal/journald-server.c @@ -943,7 +943,7 @@ static int system_journal_open(Server *s, bool flush_requested) { * the machine path */ if (s->storage == STORAGE_PERSISTENT) - (void) mkdir("/var/log/journal/", 0755); + (void) mkdir_p("/var/log/journal/", 0755); fn = strjoina("/var/log/journal/", ids); (void) mkdir(fn, 0755); diff --git a/src/kernel-install/Makefile b/src/kernel-install/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/kernel-install/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/libsystemd-network/Makefile b/src/libsystemd-network/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/libsystemd-network/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/libsystemd-network/sd-lldp.c b/src/libsystemd-network/sd-lldp.c index fddda97f52..6a2c05185d 100644 --- a/src/libsystemd-network/sd-lldp.c +++ b/src/libsystemd-network/sd-lldp.c @@ -133,8 +133,6 @@ static int lldp_receive_frame(sd_lldp *lldp, tlv_packet *tlv) { lldp->statistics.stats_frames_in_total ++; - return 0; - out: if (r < 0) log_lldp("Receive frame failed: %s", strerror(-r)); diff --git a/src/libsystemd-terminal/.gitignore b/src/libsystemd-terminal/.gitignore new file mode 100644 index 0000000000..7de83bd3e9 --- /dev/null +++ b/src/libsystemd-terminal/.gitignore @@ -0,0 +1 @@ +/unifont-glyph-array.bin diff --git a/src/libsystemd-terminal/grdev-drm.c b/src/libsystemd-terminal/grdev-drm.c index 30c1a726eb..10c13e348a 100644 --- a/src/libsystemd-terminal/grdev-drm.c +++ b/src/libsystemd-terminal/grdev-drm.c @@ -2584,7 +2584,7 @@ static int unmanaged_card_new(grdev_card **out, grdev_session *session, struct u } else { /* We might get DRM-Master implicitly on open(); drop it immediately * so we acquire it only once we're actually enabled. We don't - * really care whether this call fails or not, but lets log any + * really care whether this call fails or not, but let's log any * weird errors, anyway. */ r = ioctl(fd, DRM_IOCTL_DROP_MASTER, 0); if (r < 0 && errno != EACCES && errno != EINVAL) @@ -2777,7 +2777,7 @@ static int managed_card_resume_device_fn(sd_bus_message *signal, if (cm->card.fd < 0) { /* This shouldn't happen. We should already own an FD from - * TakeDevice(). However, lets be safe and use this FD in case + * TakeDevice(). However, let's be safe and use this FD in case * we really don't have one. There is no harm in doing this * and our code works fine this way. */ fd = fcntl(fd, F_DUPFD_CLOEXEC, 3); diff --git a/src/libsystemd-terminal/unifont-glyph-array.bin b/src/libsystemd-terminal/unifont-glyph-array.bin Binary files differdeleted file mode 100644 index 84aaab7c18..0000000000 --- a/src/libsystemd-terminal/unifont-glyph-array.bin +++ /dev/null diff --git a/src/libsystemd/.gitignore b/src/libsystemd/.gitignore new file mode 100644 index 0000000000..50a1692374 --- /dev/null +++ b/src/libsystemd/.gitignore @@ -0,0 +1 @@ +/libsystemd.pc diff --git a/src/libsystemd/Makefile b/src/libsystemd/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/libsystemd/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym index 809db1f6cc..7bf1d66dde 100644 --- a/src/libsystemd/libsystemd.sym +++ b/src/libsystemd/libsystemd.sym @@ -459,3 +459,11 @@ global: sd_event_source_get_signal; sd_event_source_get_child_pid; } LIBSYSTEMD_220; + +LIBSYSTEMD_222 { +global: + /* sd-bus */ + sd_bus_emit_object_added; + sd_bus_emit_object_removed; + sd_bus_flush_close_unref; +} LIBSYSTEMD_221; diff --git a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION index 859e2715f9..6aeb11364a 100644 --- a/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION +++ b/src/libsystemd/sd-bus/GVARIANT-SERIALIZATION @@ -25,8 +25,8 @@ The header consists of the following: = 12 bytes -This header is then followed by the the fields array, whose first -value is a 32bit array size. +This header is then followed by the fields array, whose first value is +a 32bit array size. When using GVariant we keep the basic structure in place, only slightly alter the header, and define protocol version '2'. The new diff --git a/src/libsystemd/sd-bus/Makefile b/src/libsystemd/sd-bus/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/src/libsystemd/sd-bus/Makefile @@ -0,0 +1 @@ +../../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-bus/bus-common-errors.h b/src/libsystemd/sd-bus/bus-common-errors.h index b17b62ac93..0dbfbddcf6 100644 --- a/src/libsystemd/sd-bus/bus-common-errors.h +++ b/src/libsystemd/sd-bus/bus-common-errors.h @@ -58,6 +58,7 @@ #define BUS_ERROR_DEVICE_NOT_TAKEN "org.freedesktop.login1.DeviceNotTaken" #define BUS_ERROR_OPERATION_IN_PROGRESS "org.freedesktop.login1.OperationInProgress" #define BUS_ERROR_SLEEP_VERB_NOT_SUPPORTED "org.freedesktop.login1.SleepVerbNotSupported" +#define BUS_ERROR_SESSION_BUSY "org.freedesktop.login1.SessionBusy" #define BUS_ERROR_AUTOMATIC_TIME_SYNC_ENABLED "org.freedesktop.timedate1.AutomaticTimeSyncEnabled" diff --git a/src/libsystemd/sd-bus/bus-control.c b/src/libsystemd/sd-bus/bus-control.c index 7a59702cb2..a38c5c50fc 100644 --- a/src/libsystemd/sd-bus/bus-control.c +++ b/src/libsystemd/sd-bus/bus-control.c @@ -1219,7 +1219,7 @@ int bus_add_match_internal_kernel( size_t sz; const char *sender = NULL; size_t sender_length = 0; - uint64_t src_id = KDBUS_MATCH_ID_ANY; + uint64_t src_id = KDBUS_MATCH_ID_ANY, dst_id = KDBUS_MATCH_ID_ANY; bool using_bloom = false; unsigned i; bool matches_name_change = true; @@ -1332,13 +1332,21 @@ int bus_add_match_internal_kernel( break; } - case BUS_MATCH_DESTINATION: - /* The bloom filter does not include - the destination, since it is only - available for broadcast messages - which do not carry a destination - since they are undirected. */ + case BUS_MATCH_DESTINATION: { + /* + * Kernel only supports matching on destination IDs, but + * not on destination names. So just skip the + * destination name restriction and verify it in + * user-space on retrieval. + */ + r = bus_kernel_parse_unique_name(c->value_str, &dst_id); + if (r < 0) + return r; + else if (r > 0) + sz += ALIGN8(offsetof(struct kdbus_item, id) + sizeof(uint64_t)); + break; + } case BUS_MATCH_ROOT: case BUS_MATCH_VALUE: @@ -1365,6 +1373,13 @@ int bus_add_match_internal_kernel( item = KDBUS_ITEM_NEXT(item); } + if (dst_id != KDBUS_MATCH_ID_ANY) { + item->size = offsetof(struct kdbus_item, id) + sizeof(uint64_t); + item->type = KDBUS_ITEM_DST_ID; + item->id = dst_id; + item = KDBUS_ITEM_NEXT(item); + } + if (using_bloom) { item->size = offsetof(struct kdbus_item, data64) + bus->bloom_size; item->type = KDBUS_ITEM_BLOOM_MASK; diff --git a/src/libsystemd/sd-bus/bus-kernel.c b/src/libsystemd/sd-bus/bus-kernel.c index f08db2da89..e3fac01f92 100644 --- a/src/libsystemd/sd-bus/bus-kernel.c +++ b/src/libsystemd/sd-bus/bus-kernel.c @@ -1385,15 +1385,16 @@ int bus_kernel_read_message(sd_bus *bus, bool hint_priority, int64_t priority) { r = 0; } - } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL) + if (r <= 0) + close_kdbus_msg(bus, k); + } else if (k->payload_type == KDBUS_PAYLOAD_KERNEL) { r = bus_kernel_translate_message(bus, k); - else { + close_kdbus_msg(bus, k); + } else { log_debug("Ignoring message with unknown payload type %llu.", (unsigned long long) k->payload_type); r = 0; - } - - if (r <= 0) close_kdbus_msg(bus, k); + } return r < 0 ? r : 1; } diff --git a/src/libsystemd/sd-bus/bus-objects.c b/src/libsystemd/sd-bus/bus-objects.c index e4bbd880e5..2eaa7de306 100644 --- a/src/libsystemd/sd-bus/bus-objects.c +++ b/src/libsystemd/sd-bus/bus-objects.c @@ -2261,7 +2261,7 @@ static int object_added_append_all(sd_bus *bus, sd_bus_message *m, const char *p return 0; } -int sd_bus_emit_object_added(sd_bus *bus, const char *path) { +_public_ int sd_bus_emit_object_added(sd_bus *bus, const char *path) { BUS_DONT_DESTROY(bus); _cleanup_bus_message_unref_ sd_bus_message *m = NULL; @@ -2424,7 +2424,7 @@ static int object_removed_append_all(sd_bus *bus, sd_bus_message *m, const char return 0; } -int sd_bus_emit_object_removed(sd_bus *bus, const char *path) { +_public_ int sd_bus_emit_object_removed(sd_bus *bus, const char *path) { BUS_DONT_DESTROY(bus); _cleanup_bus_message_unref_ sd_bus_message *m = NULL; diff --git a/src/libsystemd/sd-bus/busctl.c b/src/libsystemd/sd-bus/busctl.c index 39caa4e7d6..6aaaf0e5ec 100644 --- a/src/libsystemd/sd-bus/busctl.c +++ b/src/libsystemd/sd-bus/busctl.c @@ -1137,6 +1137,7 @@ static int monitor(sd_bus *bus, char *argv[], int (*dump)(sd_bus_message *m, FIL if (m) { dump(m, stdout); + fflush(stdout); if (sd_bus_message_is_signal(m, "org.freedesktop.DBus.Local", "Disconnected") > 0) { log_info("Connection terminated, exiting."); @@ -1973,7 +1974,7 @@ static int busctl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char *argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; log_parse_environment(); diff --git a/src/libsystemd/sd-bus/kdbus.h b/src/libsystemd/sd-bus/kdbus.h index 00a6e142c9..ecffc6b13c 100644 --- a/src/libsystemd/sd-bus/kdbus.h +++ b/src/libsystemd/sd-bus/kdbus.h @@ -374,6 +374,7 @@ enum kdbus_item_type { KDBUS_ITEM_ATTACH_FLAGS_RECV, KDBUS_ITEM_ID, KDBUS_ITEM_NAME, + KDBUS_ITEM_DST_ID, /* keep these item types in sync with KDBUS_ATTACH_* flags */ _KDBUS_ITEM_ATTACH_BASE = 0x1000, diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c index 5dd6468707..0ca225c617 100644 --- a/src/libsystemd/sd-bus/sd-bus.c +++ b/src/libsystemd/sd-bus/sd-bus.c @@ -1428,6 +1428,17 @@ _public_ void sd_bus_close(sd_bus *bus) { * ioctl on the fd when they are freed. */ } +_public_ sd_bus* sd_bus_flush_close_unref(sd_bus *bus) { + + if (!bus) + return NULL; + + sd_bus_flush(bus); + sd_bus_close(bus); + + return sd_bus_unref(bus); +} + static void bus_enter_closing(sd_bus *bus) { assert(bus); diff --git a/src/libsystemd/sd-bus/test-bus-chat.c b/src/libsystemd/sd-bus/test-bus-chat.c index 046e999008..754335b5e7 100644 --- a/src/libsystemd/sd-bus/test-bus-chat.c +++ b/src/libsystemd/sd-bus/test-bus-chat.c @@ -262,7 +262,7 @@ fail: static void* client1(void*p) { _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; const char *hello; int r; @@ -361,7 +361,7 @@ static int quit_callback(sd_bus_message *m, void *userdata, sd_bus_error *ret_er static void* client2(void*p) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; bool quit = false; const char *mid; diff --git a/src/libsystemd/sd-bus/test-bus-gvariant.c b/src/libsystemd/sd-bus/test-bus-gvariant.c index 22ea00c2fb..9b7dd2e499 100644 --- a/src/libsystemd/sd-bus/test-bus-gvariant.c +++ b/src/libsystemd/sd-bus/test-bus-gvariant.c @@ -132,7 +132,7 @@ static void test_bus_gvariant_get_alignment(void) { static void test_marshal(void) { _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *n = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; _cleanup_free_ void *blob; size_t sz; int r; diff --git a/src/libsystemd/sd-bus/test-bus-match.c b/src/libsystemd/sd-bus/test-bus-match.c index a1687b1c7b..83cb5c62c2 100644 --- a/src/libsystemd/sd-bus/test-bus-match.c +++ b/src/libsystemd/sd-bus/test-bus-match.c @@ -92,7 +92,7 @@ int main(int argc, char *argv[]) { }; _cleanup_bus_message_unref_ sd_bus_message *m = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; enum bus_match_node_type i; sd_bus_slot slots[19]; int r; diff --git a/src/libsystemd/sd-daemon/Makefile b/src/libsystemd/sd-daemon/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/libsystemd/sd-daemon/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-event/Makefile b/src/libsystemd/sd-event/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/src/libsystemd/sd-event/Makefile @@ -0,0 +1 @@ +../../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-hwdb/Makefile b/src/libsystemd/sd-hwdb/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/src/libsystemd/sd-hwdb/Makefile @@ -0,0 +1 @@ +../../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-id128/Makefile b/src/libsystemd/sd-id128/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/src/libsystemd/sd-id128/Makefile @@ -0,0 +1 @@ +../../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-login/Makefile b/src/libsystemd/sd-login/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/libsystemd/sd-login/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-netlink/Makefile b/src/libsystemd/sd-netlink/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/src/libsystemd/sd-netlink/Makefile @@ -0,0 +1 @@ +../../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 7290f4e875..6f51ebe73d 100644 --- a/src/libsystemd/sd-netlink/netlink-internal.h +++ b/src/libsystemd/sd-netlink/netlink-internal.h @@ -92,18 +92,25 @@ struct sd_netlink { sd_event *event; }; +struct netlink_attribute { + size_t offset; /* offset from hdr to attribute */ +}; + +struct netlink_container { + const struct NLTypeSystem *type_system; /* the type system of the container */ + size_t offset; /* offset from hdr to the start of the container */ + struct netlink_attribute *attributes; + unsigned short n_attributes; /* number of attributes in container */ +}; + struct sd_netlink_message { RefCount n_ref; sd_netlink *rtnl; struct nlmsghdr *hdr; - const struct NLTypeSystem *(container_type_system[RTNL_CONTAINER_DEPTH]); /* the type of the container and all its parents */ - size_t container_offsets[RTNL_CONTAINER_DEPTH]; /* offset from hdr to each container's start */ + struct netlink_container containers[RTNL_CONTAINER_DEPTH]; unsigned n_containers; /* number of containers */ - size_t next_rta_offset; /* offset from hdr to next rta */ - size_t *rta_offset_tb[RTNL_CONTAINER_DEPTH]; - unsigned short rta_tb_size[RTNL_CONTAINER_DEPTH]; bool sealed:1; bool broadcast:1; @@ -122,14 +129,6 @@ int socket_read_message(sd_netlink *nl); int rtnl_rqueue_make_room(sd_netlink *rtnl); int rtnl_rqueue_partial_make_room(sd_netlink *rtnl); -int rtnl_message_read_internal(sd_netlink_message *m, unsigned short type, void **data); -int rtnl_message_parse(sd_netlink_message *m, - size_t **rta_offset_tb, - unsigned short *rta_tb_size, - int max, - struct rtattr *rta, - unsigned int rt_len); - /* Make sure callbacks don't destroy the rtnl connection */ #define RTNL_DONT_DESTROY(rtnl) \ _cleanup_netlink_unref_ _unused_ sd_netlink *_dont_destroy_##rtnl = sd_netlink_ref(rtnl) diff --git a/src/libsystemd/sd-netlink/netlink-message.c b/src/libsystemd/sd-netlink/netlink-message.c index 87324fc2f7..13573dcea8 100644 --- a/src/libsystemd/sd-netlink/netlink-message.c +++ b/src/libsystemd/sd-netlink/netlink-message.c @@ -34,7 +34,7 @@ #include "netlink-internal.h" #include "netlink-types.h" -#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->container_offsets[i]) : NULL) +#define GET_CONTAINER(m, i) ((i) < (m)->n_containers ? (struct rtattr*)((uint8_t*)(m)->hdr + (m)->containers[i].offset) : NULL) #define PUSH_CONTAINER(m, new) (m)->container_offsets[(m)->n_containers ++] = (uint8_t*)(new) - (uint8_t*)(m)->hdr; #define RTA_TYPE(rta) ((rta)->rta_type & NLA_TYPE_MASK) @@ -68,15 +68,18 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { size_t size; int r; - r = type_system_get_type(NULL, &nl_type, type); + r = type_system_get_type(&type_system_root, &nl_type, type); if (r < 0) return r; + if (type_get_type(nl_type) != NETLINK_TYPE_NESTED) + return -EINVAL; + r = message_new_empty(rtnl, &m); if (r < 0) return r; - size = NLMSG_SPACE(nl_type->size); + size = NLMSG_SPACE(type_get_size(nl_type)); assert(size >= sizeof(struct nlmsghdr)); m->hdr = malloc0(size); @@ -85,7 +88,7 @@ int message_new(sd_netlink *rtnl, sd_netlink_message **ret, uint16_t type) { m->hdr->nlmsg_flags = NLM_F_REQUEST | NLM_F_ACK; - m->container_type_system[0] = nl_type->type_system; + type_get_type_system(nl_type, &m->containers[0].type_system); m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = type; @@ -126,7 +129,7 @@ sd_netlink_message *sd_netlink_message_unref(sd_netlink_message *m) { free(m->hdr); for (i = 0; i <= m->n_containers; i++) - free(m->rta_offset_tb[i]); + free(m->containers[i].attributes); sd_netlink_message_unref(m->next); @@ -214,18 +217,22 @@ static int add_rtattr(sd_netlink_message *m, unsigned short type, const void *da return offset; } -static int message_attribute_has_type(sd_netlink_message *m, uint16_t attribute_type, uint16_t data_type) { +static int message_attribute_has_type(sd_netlink_message *m, size_t *out_size, uint16_t attribute_type, uint16_t data_type) { const NLType *type; int r; - r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type); + assert(m); + + r = type_system_get_type(m->containers[m->n_containers].type_system, &type, attribute_type); if (r < 0) return r; - if (type->type != data_type) + if (type_get_type(type) != data_type) return -EINVAL; - return type->size; + if (out_size) + *out_size = type_get_size(type); + return 0; } int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, const char *data) { @@ -236,11 +243,9 @@ int sd_netlink_message_append_string(sd_netlink_message *m, unsigned short type, assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NLA_STRING); + r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_STRING); if (r < 0) return r; - else - size = (size_t)r; if (size) { length = strnlen(data, size+1); @@ -262,7 +267,7 @@ int sd_netlink_message_append_u8(sd_netlink_message *m, unsigned short type, uin assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NLA_U8); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U8); if (r < 0) return r; @@ -280,7 +285,7 @@ int sd_netlink_message_append_u16(sd_netlink_message *m, unsigned short type, ui assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NLA_U16); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U16); if (r < 0) return r; @@ -297,7 +302,7 @@ int sd_netlink_message_append_u32(sd_netlink_message *m, unsigned short type, ui assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = message_attribute_has_type(m, type, NLA_U32); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U32); if (r < 0) return r; @@ -315,7 +320,7 @@ int sd_netlink_message_append_in_addr(sd_netlink_message *m, unsigned short type assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NLA_IN_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -333,7 +338,7 @@ int sd_netlink_message_append_in6_addr(sd_netlink_message *m, unsigned short typ assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NLA_IN_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; @@ -351,7 +356,7 @@ int sd_netlink_message_append_ether_addr(sd_netlink_message *m, unsigned short t assert_return(!m->sealed, -EPERM); assert_return(data, -EINVAL); - r = message_attribute_has_type(m, type, NLA_ETHER_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_ETHER_ADDR); if (r < 0) return r; @@ -369,7 +374,7 @@ int sd_netlink_message_append_cache_info(sd_netlink_message *m, unsigned short t assert_return(!m->sealed, -EPERM); assert_return(info, -EINVAL); - r = message_attribute_has_type(m, type, NLA_CACHE_INFO); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_CACHE_INFO); if (r < 0) return r; @@ -388,34 +393,31 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type assert_return(!m->sealed, -EPERM); assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -ERANGE); - r = message_attribute_has_type(m, type, NLA_NESTED); + r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_NESTED); if (r < 0) { const NLTypeSystemUnion *type_system_union; int family; - r = message_attribute_has_type(m, type, NLA_UNION); + r = message_attribute_has_type(m, &size, type, NETLINK_TYPE_UNION); if (r < 0) return r; - size = (size_t) r; r = sd_rtnl_message_get_family(m, &family); if (r < 0) return r; - r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type); + r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type); if (r < 0) return r; r = type_system_union_protocol_get_type_system(type_system_union, - &m->container_type_system[m->n_containers + 1], + &m->containers[m->n_containers + 1].type_system, family); if (r < 0) return r; } else { - size = (size_t)r; - - r = type_system_get_type_system(m->container_type_system[m->n_containers], - &m->container_type_system[m->n_containers + 1], + r = type_system_get_type_system(m->containers[m->n_containers].type_system, + &m->containers[m->n_containers + 1].type_system, type); if (r < 0) return r; @@ -425,7 +427,7 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type if (r < 0) return r; - m->container_offsets[m->n_containers ++] = r; + m->containers[m->n_containers ++].offset = r; return 0; } @@ -437,12 +439,12 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor assert_return(m, -EINVAL); assert_return(!m->sealed, -EPERM); - r = type_system_get_type_system_union(m->container_type_system[m->n_containers], &type_system_union, type); + r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, type); if (r < 0) return r; r = type_system_union_get_type_system(type_system_union, - &m->container_type_system[m->n_containers + 1], + &m->containers[m->n_containers + 1].type_system, key); if (r < 0) return r; @@ -452,11 +454,11 @@ int sd_netlink_message_open_container_union(sd_netlink_message *m, unsigned shor return r; /* do we evere need non-null size */ - r = add_rtattr(m, type, NULL, 0); + r = add_rtattr(m, type | NLA_F_NESTED, NULL, 0); if (r < 0) return r; - m->container_offsets[m->n_containers ++] = r; + m->containers[m->n_containers ++].offset = r; return 0; } @@ -467,26 +469,29 @@ int sd_netlink_message_close_container(sd_netlink_message *m) { assert_return(!m->sealed, -EPERM); assert_return(m->n_containers > 0, -EINVAL); - m->container_type_system[m->n_containers] = NULL; + m->containers[m->n_containers].type_system = NULL; m->n_containers --; return 0; } -int rtnl_message_read_internal(sd_netlink_message *m, unsigned short type, void **data) { +static int netlink_message_read_internal(sd_netlink_message *m, unsigned short type, void **data) { + struct netlink_attribute *attribute; struct rtattr *rta; assert_return(m, -EINVAL); assert_return(m->sealed, -EPERM); assert_return(data, -EINVAL); assert(m->n_containers <= RTNL_CONTAINER_DEPTH); - assert(m->rta_offset_tb[m->n_containers]); - assert(type < m->rta_tb_size[m->n_containers]); + assert(m->containers[m->n_containers].attributes); + assert(type < m->containers[m->n_containers].n_attributes); - if(!m->rta_offset_tb[m->n_containers][type]) + attribute = &m->containers[m->n_containers].attributes[type]; + + if(!attribute->offset) return -ENODATA; - rta = (struct rtattr*)((uint8_t *) m->hdr + m->rta_offset_tb[m->n_containers][type]); + rta = (struct rtattr*)((uint8_t *) m->hdr + attribute->offset); *data = RTA_DATA(rta); @@ -499,11 +504,11 @@ int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, c assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_STRING); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_STRING); if (r < 0) return r; - r = rtnl_message_read_internal(m, type, &attr_data); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if (strnlen(attr_data, r) >= (size_t) r) @@ -521,11 +526,11 @@ int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8 assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_U8); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U8); if (r < 0) return r; - r = rtnl_message_read_internal(m, type, &attr_data); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t) r < sizeof(uint8_t)) @@ -543,11 +548,11 @@ int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_U16); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U16); if (r < 0) return r; - r = rtnl_message_read_internal(m, type, &attr_data); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t) r < sizeof(uint16_t)) @@ -565,11 +570,11 @@ int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_U32); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_U32); if (r < 0) return r; - r = rtnl_message_read_internal(m, type, &attr_data); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(uint32_t)) @@ -587,11 +592,11 @@ int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short typ assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_ETHER_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_ETHER_ADDR); if (r < 0) return r; - r = rtnl_message_read_internal(m, type, &attr_data); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(struct ether_addr)) @@ -609,11 +614,11 @@ int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short typ assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_CACHE_INFO); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_CACHE_INFO); if (r < 0) return r; - r = rtnl_message_read_internal(m, type, &attr_data); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(struct ifa_cacheinfo)) @@ -631,11 +636,11 @@ int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type, assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_IN_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; - r = rtnl_message_read_internal(m, type, &attr_data); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(struct in_addr)) @@ -653,11 +658,11 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, assert_return(m, -EINVAL); - r = message_attribute_has_type(m, type, NLA_IN_ADDR); + r = message_attribute_has_type(m, NULL, type, NETLINK_TYPE_IN_ADDR); if (r < 0) return r; - r = rtnl_message_read_internal(m, type, &attr_data); + r = netlink_message_read_internal(m, type, &attr_data); if (r < 0) return r; else if ((size_t)r < sizeof(struct in6_addr)) @@ -669,34 +674,71 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, return 0; } -int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type) { +static int netlink_container_parse(sd_netlink_message *m, + struct netlink_container *container, + int count, + struct rtattr *rta, + unsigned int rt_len) { + _cleanup_free_ struct netlink_attribute *attributes = NULL; + + attributes = new0(struct netlink_attribute, count); + if(!attributes) + return -ENOMEM; + + for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) { + unsigned short type; + + type = RTA_TYPE(rta); + + /* if the kernel is newer than the headers we used + when building, we ignore out-of-range attributes */ + if (type >= count) + continue; + + if (attributes[type].offset) + log_debug("rtnl: message parse - overwriting repeated attribute"); + + attributes[type].offset = (uint8_t *) rta - (uint8_t *) m->hdr; + } + + container->attributes = attributes; + attributes = NULL; + container->n_attributes = count; + + return 0; +} + +int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short type_id) { const NLType *nl_type; const NLTypeSystem *type_system; void *container; + uint16_t type; size_t size; int r; assert_return(m, -EINVAL); assert_return(m->n_containers < RTNL_CONTAINER_DEPTH, -EINVAL); - r = type_system_get_type(m->container_type_system[m->n_containers], + r = type_system_get_type(m->containers[m->n_containers].type_system, &nl_type, - type); + type_id); if (r < 0) return r; - if (nl_type->type == NLA_NESTED) { - r = type_system_get_type_system(m->container_type_system[m->n_containers], + type = type_get_type(nl_type); + + if (type == NETLINK_TYPE_NESTED) { + r = type_system_get_type_system(m->containers[m->n_containers].type_system, &type_system, - type); + type_id); if (r < 0) return r; - } else if (nl_type->type == NLA_UNION) { + } else if (type == NETLINK_TYPE_UNION) { const NLTypeSystemUnion *type_system_union; - r = type_system_get_type_system_union(m->container_type_system[m->n_containers], + r = type_system_get_type_system_union(m->containers[m->n_containers].type_system, &type_system_union, - type); + type_id); if (r < 0) return r; @@ -739,7 +781,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ } else return -EINVAL; - r = rtnl_message_read_internal(m, type, &container); + r = netlink_message_read_internal(m, type_id, &container); if (r < 0) return r; else @@ -747,18 +789,17 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ m->n_containers ++; - r = rtnl_message_parse(m, - &m->rta_offset_tb[m->n_containers], - &m->rta_tb_size[m->n_containers], - type_system->max, - container, - size); + r = netlink_container_parse(m, + &m->containers[m->n_containers], + type_system_get_count(type_system), + container, + size); if (r < 0) { m->n_containers --; return r; } - m->container_type_system[m->n_containers] = type_system; + m->containers[m->n_containers].type_system = type_system; return 0; } @@ -768,9 +809,9 @@ int sd_netlink_message_exit_container(sd_netlink_message *m) { assert_return(m->sealed, -EINVAL); assert_return(m->n_containers > 0, -EINVAL); - free(m->rta_offset_tb[m->n_containers]); - m->rta_offset_tb[m->n_containers] = NULL; - m->container_type_system[m->n_containers] = NULL; + free(m->containers[m->n_containers].attributes); + m->containers[m->n_containers].attributes = NULL; + m->containers[m->n_containers].type_system = NULL; m->n_containers --; @@ -805,43 +846,10 @@ int sd_netlink_message_get_errno(sd_netlink_message *m) { return err->error; } -int rtnl_message_parse(sd_netlink_message *m, - size_t **rta_offset_tb, - unsigned short *rta_tb_size, - int max, - struct rtattr *rta, - unsigned int rt_len) { - unsigned short type; - size_t *tb; - - tb = new0(size_t, max + 1); - if(!tb) - return -ENOMEM; - - *rta_tb_size = max + 1; - - for (; RTA_OK(rta, rt_len); rta = RTA_NEXT(rta, rt_len)) { - type = RTA_TYPE(rta); - - /* if the kernel is newer than the headers we used - when building, we ignore out-of-range attributes - */ - if (type > max) - continue; - - if (tb[type]) - log_debug("rtnl: message parse - overwriting repeated attribute"); - - tb[type] = (uint8_t *) rta - (uint8_t *) m->hdr; - } - - *rta_offset_tb = tb; - - return 0; -} - int sd_netlink_message_rewind(sd_netlink_message *m) { - const NLType *type; + const NLType *nl_type; + uint16_t type; + size_t size; unsigned i; int r; @@ -852,39 +860,38 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { rtnl_message_seal(m); for (i = 1; i <= m->n_containers; i++) { - free(m->rta_offset_tb[i]); - m->rta_offset_tb[i] = NULL; - m->rta_tb_size[i] = 0; - m->container_type_system[i] = NULL; + free(m->containers[i].attributes); + m->containers[i].attributes = NULL; } m->n_containers = 0; - if (m->rta_offset_tb[0]) { + if (m->containers[0].attributes) { /* top-level attributes have already been parsed */ return 0; } assert(m->hdr); - r = type_system_get_type(NULL, &type, m->hdr->nlmsg_type); + r = type_system_get_type(&type_system_root, &nl_type, m->hdr->nlmsg_type); if (r < 0) return r; - if (type->type == NLA_NESTED) { - const NLTypeSystem *type_system = type->type_system; + type = type_get_type(nl_type); + size = type_get_size(nl_type); + + if (type == NETLINK_TYPE_NESTED) { + const NLTypeSystem *type_system; - assert(type_system); + type_get_type_system(nl_type, &type_system); - m->container_type_system[0] = type_system; + m->containers[0].type_system = type_system; - r = rtnl_message_parse(m, - &m->rta_offset_tb[m->n_containers], - &m->rta_tb_size[m->n_containers], - type_system->max, - (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + - NLMSG_ALIGN(type->size)), - NLMSG_PAYLOAD(m->hdr, type->size)); + r = netlink_container_parse(m, + &m->containers[m->n_containers], + type_system_get_count(type_system), + (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)), + NLMSG_PAYLOAD(m->hdr, size)); if (r < 0) return r; } diff --git a/src/libsystemd/sd-netlink/netlink-socket.c b/src/libsystemd/sd-netlink/netlink-socket.c index 8136cf36ae..84ff7c38c9 100644 --- a/src/libsystemd/sd-netlink/netlink-socket.c +++ b/src/libsystemd/sd-netlink/netlink-socket.c @@ -243,7 +243,7 @@ int socket_read_message(sd_netlink *rtnl) { } /* check that we support this message type */ - r = type_system_get_type(NULL, &nl_type, new_msg->nlmsg_type); + r = type_system_get_type(&type_system_root, &nl_type, new_msg->nlmsg_type); if (r < 0) { if (r == -EOPNOTSUPP) log_debug("sd-netlink: ignored message with unknown type: %i", @@ -253,7 +253,7 @@ int socket_read_message(sd_netlink *rtnl) { } /* check that the size matches the message type */ - if (new_msg->nlmsg_len < NLMSG_LENGTH(nl_type->size)) { + if (new_msg->nlmsg_len < NLMSG_LENGTH(type_get_size(nl_type))) { log_debug("sd-netlink: message larger than expected, dropping"); continue; } diff --git a/src/libsystemd/sd-netlink/netlink-types.c b/src/libsystemd/sd-netlink/netlink-types.c index 273033770f..74ac2ab344 100644 --- a/src/libsystemd/sd-netlink/netlink-types.c +++ b/src/libsystemd/sd-netlink/netlink-types.c @@ -39,152 +39,195 @@ #include "netlink-types.h" #include "missing.h" +/* Maximum ARP IP target defined in kernel */ +#define BOND_MAX_ARP_TARGETS 16 + +typedef enum { + BOND_ARP_TARGETS_0, + BOND_ARP_TARGETS_1, + BOND_ARP_TARGETS_2, + BOND_ARP_TARGETS_3, + BOND_ARP_TARGETS_4, + BOND_ARP_TARGETS_5, + BOND_ARP_TARGETS_6, + BOND_ARP_TARGETS_7, + BOND_ARP_TARGETS_8, + BOND_ARP_TARGETS_9, + BOND_ARP_TARGETS_10, + BOND_ARP_TARGETS_11, + BOND_ARP_TARGETS_12, + BOND_ARP_TARGETS_13, + BOND_ARP_TARGETS_14, + BOND_ARP_TARGETS_MAX = BOND_MAX_ARP_TARGETS, +} BondArpTargets; + +struct NLType { + uint16_t type; + size_t size; + const NLTypeSystem *type_system; + const NLTypeSystemUnion *type_system_union; +}; + +struct NLTypeSystem { + uint16_t count; + const NLType *types; +}; + static const NLTypeSystem rtnl_link_type_system; +static const NLType empty_types[1] = { + /* fake array to avoid .types==NULL, which denotes invalid type-systems */ +}; + +static const NLTypeSystem empty_type_system = { + .count = 0, + .types = empty_types, +}; + static const NLType rtnl_link_info_data_veth_types[VETH_INFO_MAX + 1] = { - [VETH_INFO_PEER] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [VETH_INFO_PEER] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, }; static const NLType rtnl_link_info_data_ipvlan_types[IFLA_IPVLAN_MAX + 1] = { - [IFLA_IPVLAN_MODE] = { .type = NLA_U16 }, + [IFLA_IPVLAN_MODE] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_macvlan_types[IFLA_MACVLAN_MAX + 1] = { - [IFLA_MACVLAN_MODE] = { .type = NLA_U32 }, - [IFLA_MACVLAN_FLAGS] = { .type = NLA_U16 }, + [IFLA_MACVLAN_MODE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_MACVLAN_FLAGS] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_bridge_types[IFLA_BRIDGE_MAX + 1] = { - [IFLA_BRIDGE_FLAGS] = { .type = NLA_U16 }, - [IFLA_BRIDGE_MODE] = { .type = NLA_U16 }, + [IFLA_BRIDGE_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRIDGE_MODE] = { .type = NETLINK_TYPE_U16 }, /* - [IFLA_BRIDGE_VLAN_INFO] = { .type = NLA_BINARY, + [IFLA_BRIDGE_VLAN_INFO] = { .type = NETLINK_TYPE_BINARY, .len = sizeof(struct bridge_vlan_info), }, */ }; static const NLType rtnl_link_info_data_vlan_types[IFLA_VLAN_MAX + 1] = { - [IFLA_VLAN_ID] = { .type = NLA_U16 }, + [IFLA_VLAN_ID] = { .type = NETLINK_TYPE_U16 }, /* [IFLA_VLAN_FLAGS] = { .len = sizeof(struct ifla_vlan_flags) }, - [IFLA_VLAN_EGRESS_QOS] = { .type = NLA_NESTED }, - [IFLA_VLAN_INGRESS_QOS] = { .type = NLA_NESTED }, + [IFLA_VLAN_EGRESS_QOS] = { .type = NETLINK_TYPE_NESTED }, + [IFLA_VLAN_INGRESS_QOS] = { .type = NETLINK_TYPE_NESTED }, */ - [IFLA_VLAN_PROTOCOL] = { .type = NLA_U16 }, + [IFLA_VLAN_PROTOCOL] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_vxlan_types[IFLA_VXLAN_MAX+1] = { - [IFLA_VXLAN_ID] = { .type = NLA_U32 }, - [IFLA_VXLAN_GROUP] = {.type = NLA_IN_ADDR }, - [IFLA_VXLAN_LINK] = { .type = NLA_U32 }, - [IFLA_VXLAN_LOCAL] = { .type = NLA_U32}, - [IFLA_VXLAN_TTL] = { .type = NLA_U8 }, - [IFLA_VXLAN_TOS] = { .type = NLA_U8 }, - [IFLA_VXLAN_LEARNING] = { .type = NLA_U8 }, - [IFLA_VXLAN_AGEING] = { .type = NLA_U32 }, - [IFLA_VXLAN_LIMIT] = { .type = NLA_U32 }, - [IFLA_VXLAN_PORT_RANGE] = { .type = NLA_U32}, - [IFLA_VXLAN_PROXY] = { .type = NLA_U8 }, - [IFLA_VXLAN_RSC] = { .type = NLA_U8 }, - [IFLA_VXLAN_L2MISS] = { .type = NLA_U8 }, - [IFLA_VXLAN_L3MISS] = { .type = NLA_U8 }, + [IFLA_VXLAN_ID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_GROUP] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VXLAN_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_LOCAL] = { .type = NETLINK_TYPE_U32}, + [IFLA_VXLAN_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_LEARNING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_AGEING] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_LIMIT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VXLAN_PORT_RANGE] = { .type = NETLINK_TYPE_U32}, + [IFLA_VXLAN_PROXY] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_RSC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_L2MISS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_VXLAN_L3MISS] = { .type = NETLINK_TYPE_U8 }, }; static const NLType rtnl_bond_arp_target_types[BOND_ARP_TARGETS_MAX + 1] = { - [BOND_ARP_TARGETS_0] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_1] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_2] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_3] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_4] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_5] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_6] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_7] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_8] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_9] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_10] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_11] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_12] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_13] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_14] = { .type = NLA_U32 }, - [BOND_ARP_TARGETS_MAX] = { .type = NLA_U32 }, + [BOND_ARP_TARGETS_0] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_1] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_2] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_3] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_4] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_5] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_6] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_7] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_8] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_9] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_10] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_11] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_12] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_13] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_14] = { .type = NETLINK_TYPE_U32 }, + [BOND_ARP_TARGETS_MAX] = { .type = NETLINK_TYPE_U32 }, }; static const NLTypeSystem rtnl_bond_arp_type_system = { - .max = ELEMENTSOF(rtnl_bond_arp_target_types) - 1, + .count = ELEMENTSOF(rtnl_bond_arp_target_types), .types = rtnl_bond_arp_target_types, }; static const NLType rtnl_link_info_data_bond_types[IFLA_BOND_MAX + 1] = { - [IFLA_BOND_MODE] = { .type = NLA_U8 }, - [IFLA_BOND_ACTIVE_SLAVE] = { .type = NLA_U32 }, - [IFLA_BOND_MIIMON] = { .type = NLA_U32 }, - [IFLA_BOND_UPDELAY] = { .type = NLA_U32 }, - [IFLA_BOND_DOWNDELAY] = { .type = NLA_U32 }, - [IFLA_BOND_USE_CARRIER] = { .type = NLA_U8 }, - [IFLA_BOND_ARP_INTERVAL] = { .type = NLA_U32 }, - [IFLA_BOND_ARP_IP_TARGET] = { .type = NLA_NESTED, .type_system = &rtnl_bond_arp_type_system }, - [IFLA_BOND_ARP_VALIDATE] = { .type = NLA_U32 }, - [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NLA_U32 }, - [IFLA_BOND_PRIMARY] = { .type = NLA_U32 }, - [IFLA_BOND_PRIMARY_RESELECT] = { .type = NLA_U8 }, - [IFLA_BOND_FAIL_OVER_MAC] = { .type = NLA_U8 }, - [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NLA_U8 }, - [IFLA_BOND_RESEND_IGMP] = { .type = NLA_U32 }, - [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NLA_U8 }, - [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NLA_U8 }, - [IFLA_BOND_MIN_LINKS] = { .type = NLA_U32 }, - [IFLA_BOND_LP_INTERVAL] = { .type = NLA_U32 }, - [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NLA_U32 }, - [IFLA_BOND_AD_LACP_RATE] = { .type = NLA_U8 }, - [IFLA_BOND_AD_SELECT] = { .type = NLA_U8 }, - [IFLA_BOND_AD_INFO] = { .type = NLA_NESTED }, + [IFLA_BOND_MODE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_ACTIVE_SLAVE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_MIIMON] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_UPDELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_DOWNDELAY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_USE_CARRIER] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_ARP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_ARP_IP_TARGET] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_bond_arp_type_system }, + [IFLA_BOND_ARP_VALIDATE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_ARP_ALL_TARGETS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_PRIMARY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_PRIMARY_RESELECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_FAIL_OVER_MAC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_XMIT_HASH_POLICY] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_RESEND_IGMP] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_NUM_PEER_NOTIF] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_ALL_SLAVES_ACTIVE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_MIN_LINKS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_LP_INTERVAL] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_PACKETS_PER_SLAVE] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BOND_AD_LACP_RATE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_AD_SELECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BOND_AD_INFO] = { .type = NETLINK_TYPE_NESTED }, }; static const NLType rtnl_link_info_data_iptun_types[IFLA_IPTUN_MAX + 1] = { - [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, - [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR }, - [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR }, - [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, - [IFLA_IPTUN_TOS] = { .type = NLA_U8 }, - [IFLA_IPTUN_PMTUDISC] = { .type = NLA_U8 }, - [IFLA_IPTUN_FLAGS] = { .type = NLA_U16 }, - [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, - [IFLA_IPTUN_6RD_PREFIX] = { .type = NLA_IN_ADDR }, - [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NLA_U32 }, - [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NLA_U16 }, - [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NLA_U16 }, + [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_FLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_6RD_PREFIX] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_6RD_RELAY_PREFIX] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IPTUN_6RD_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, + [IFLA_IPTUN_6RD_RELAY_PREFIXLEN] = { .type = NETLINK_TYPE_U16 }, }; static const NLType rtnl_link_info_data_ipgre_types[IFLA_GRE_MAX + 1] = { - [IFLA_GRE_LINK] = { .type = NLA_U32 }, - [IFLA_GRE_IFLAGS] = { .type = NLA_U16 }, - [IFLA_GRE_OFLAGS] = { .type = NLA_U16 }, - [IFLA_GRE_IKEY] = { .type = NLA_U32 }, - [IFLA_GRE_OKEY] = { .type = NLA_U32 }, - [IFLA_GRE_LOCAL] = { .type = NLA_IN_ADDR }, - [IFLA_GRE_REMOTE] = { .type = NLA_IN_ADDR }, - [IFLA_GRE_TTL] = { .type = NLA_U8 }, - [IFLA_GRE_TOS] = { .type = NLA_U8 }, - [IFLA_GRE_PMTUDISC] = { .type = NLA_U8 }, + [IFLA_GRE_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_IFLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_OFLAGS] = { .type = NETLINK_TYPE_U16 }, + [IFLA_GRE_IKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_OKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_GRE_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GRE_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_GRE_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_TOS] = { .type = NETLINK_TYPE_U8 }, + [IFLA_GRE_PMTUDISC] = { .type = NETLINK_TYPE_U8 }, }; static const NLType rtnl_link_info_data_ipvti_types[IFLA_VTI_MAX + 1] = { - [IFLA_VTI_LINK] = { .type = NLA_U32 }, - [IFLA_VTI_IKEY] = { .type = NLA_U32 }, - [IFLA_VTI_OKEY] = { .type = NLA_U32 }, - [IFLA_VTI_LOCAL] = { .type = NLA_IN_ADDR }, - [IFLA_VTI_REMOTE] = { .type = NLA_IN_ADDR }, + [IFLA_VTI_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_IKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_OKEY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_VTI_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_VTI_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, }; static const NLType rtnl_link_info_data_ip6tnl_types[IFLA_IPTUN_MAX + 1] = { - [IFLA_IPTUN_LINK] = { .type = NLA_U32 }, - [IFLA_IPTUN_LOCAL] = { .type = NLA_IN_ADDR }, - [IFLA_IPTUN_REMOTE] = { .type = NLA_IN_ADDR }, - [IFLA_IPTUN_TTL] = { .type = NLA_U8 }, - [IFLA_IPTUN_FLAGS] = { .type = NLA_U32 }, - [IFLA_IPTUN_PROTO] = { .type = NLA_U8 }, - [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NLA_U8 }, - [IFLA_IPTUN_FLOWINFO] = { .type = NLA_U32}, + [IFLA_IPTUN_LINK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IPTUN_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_REMOTE] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_IPTUN_TTL] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_FLAGS] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IPTUN_PROTO] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_ENCAP_LIMIT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_IPTUN_FLOWINFO] = { .type = NETLINK_TYPE_U32}, }; /* these strings must match the .kind entries in the kernel */ @@ -211,37 +254,37 @@ static const char* const nl_union_link_info_data_table[_NL_UNION_LINK_INFO_DATA_ DEFINE_STRING_TABLE_LOOKUP(nl_union_link_info_data, NLUnionLinkInfoData); static const NLTypeSystem rtnl_link_info_data_type_systems[_NL_UNION_LINK_INFO_DATA_MAX] = { - [NL_UNION_LINK_INFO_DATA_BOND] = { .max = ELEMENTSOF(rtnl_link_info_data_bond_types) - 1, + [NL_UNION_LINK_INFO_DATA_BOND] = { .count = ELEMENTSOF(rtnl_link_info_data_bond_types), .types = rtnl_link_info_data_bond_types }, - [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .max = ELEMENTSOF(rtnl_link_info_data_bridge_types) - 1, + [NL_UNION_LINK_INFO_DATA_BRIDGE] = { .count = ELEMENTSOF(rtnl_link_info_data_bridge_types), .types = rtnl_link_info_data_bridge_types }, - [NL_UNION_LINK_INFO_DATA_VLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vlan_types) - 1, + [NL_UNION_LINK_INFO_DATA_VLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vlan_types), .types = rtnl_link_info_data_vlan_types }, - [NL_UNION_LINK_INFO_DATA_VETH] = { .max = ELEMENTSOF(rtnl_link_info_data_veth_types) - 1, + [NL_UNION_LINK_INFO_DATA_VETH] = { .count = ELEMENTSOF(rtnl_link_info_data_veth_types), .types = rtnl_link_info_data_veth_types }, - [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_macvlan_types) - 1, + [NL_UNION_LINK_INFO_DATA_MACVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_macvlan_types), .types = rtnl_link_info_data_macvlan_types }, - [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvlan_types) - 1, + [NL_UNION_LINK_INFO_DATA_IPVLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvlan_types), .types = rtnl_link_info_data_ipvlan_types }, - [NL_UNION_LINK_INFO_DATA_VXLAN] = { .max = ELEMENTSOF(rtnl_link_info_data_vxlan_types) - 1, + [NL_UNION_LINK_INFO_DATA_VXLAN] = { .count = ELEMENTSOF(rtnl_link_info_data_vxlan_types), .types = rtnl_link_info_data_vxlan_types }, - [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1, + [NL_UNION_LINK_INFO_DATA_IPIP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1, + [NL_UNION_LINK_INFO_DATA_IPGRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1, + [NL_UNION_LINK_INFO_DATA_IPGRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1, + [NL_UNION_LINK_INFO_DATA_IP6GRE_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipgre_types) - 1, + [NL_UNION_LINK_INFO_DATA_IP6GRETAP_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipgre_types), .types = rtnl_link_info_data_ipgre_types }, - [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_iptun_types) - 1, + [NL_UNION_LINK_INFO_DATA_SIT_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_iptun_types), .types = rtnl_link_info_data_iptun_types }, - [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1, + [NL_UNION_LINK_INFO_DATA_VTI_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ipvti_types) - 1, + [NL_UNION_LINK_INFO_DATA_VTI6_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ipvti_types), .types = rtnl_link_info_data_ipvti_types }, - [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .max = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types) - 1, + [NL_UNION_LINK_INFO_DATA_IP6TNL_TUNNEL] = { .count = ELEMENTSOF(rtnl_link_info_data_ip6tnl_types), .types = rtnl_link_info_data_ip6tnl_types }, }; @@ -255,33 +298,33 @@ static const NLTypeSystemUnion rtnl_link_info_data_type_system_union = { }; static const NLType rtnl_link_info_types[IFLA_INFO_MAX + 1] = { - [IFLA_INFO_KIND] = { .type = NLA_STRING }, - [IFLA_INFO_DATA] = { .type = NLA_UNION, .type_system_union = &rtnl_link_info_data_type_system_union}, + [IFLA_INFO_KIND] = { .type = NETLINK_TYPE_STRING }, + [IFLA_INFO_DATA] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_link_info_data_type_system_union}, /* [IFLA_INFO_XSTATS], - [IFLA_INFO_SLAVE_KIND] = { .type = NLA_STRING }, - [IFLA_INFO_SLAVE_DATA] = { .type = NLA_NESTED }, + [IFLA_INFO_SLAVE_KIND] = { .type = NETLINK_TYPE_STRING }, + [IFLA_INFO_SLAVE_DATA] = { .type = NETLINK_TYPE_NESTED }, */ }; static const NLTypeSystem rtnl_link_info_type_system = { - .max = ELEMENTSOF(rtnl_link_info_types) - 1, + .count = ELEMENTSOF(rtnl_link_info_types), .types = rtnl_link_info_types, }; static const struct NLType rtnl_prot_info_bridge_port_types[IFLA_BRPORT_MAX + 1] = { - [IFLA_BRPORT_STATE] = { .type = NLA_U8 }, - [IFLA_BRPORT_COST] = { .type = NLA_U32 }, - [IFLA_BRPORT_PRIORITY] = { .type = NLA_U16 }, - [IFLA_BRPORT_MODE] = { .type = NLA_U8 }, - [IFLA_BRPORT_GUARD] = { .type = NLA_U8 }, - [IFLA_BRPORT_PROTECT] = { .type = NLA_U8 }, - [IFLA_BRPORT_LEARNING] = { .type = NLA_U8 }, - [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NLA_U8 }, + [IFLA_BRPORT_STATE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_COST] = { .type = NETLINK_TYPE_U32 }, + [IFLA_BRPORT_PRIORITY] = { .type = NETLINK_TYPE_U16 }, + [IFLA_BRPORT_MODE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_GUARD] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_PROTECT] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_LEARNING] = { .type = NETLINK_TYPE_U8 }, + [IFLA_BRPORT_UNICAST_FLOOD] = { .type = NETLINK_TYPE_U8 }, }; static const NLTypeSystem rtnl_prot_info_type_systems[AF_MAX] = { - [AF_BRIDGE] = { .max = ELEMENTSOF(rtnl_prot_info_bridge_port_types) - 1, + [AF_BRIDGE] = { .count = ELEMENTSOF(rtnl_prot_info_bridge_port_types), .types = rtnl_prot_info_bridge_port_types }, }; @@ -292,7 +335,7 @@ static const NLTypeSystemUnion rtnl_prot_info_type_system_union = { }; static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = { - [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, + [IFLA_INET6_FLAGS] = { .type = NETLINK_TYPE_U32 }, /* IFLA_INET6_CONF, IFLA_INET6_STATS, @@ -300,114 +343,114 @@ static const struct NLType rtnl_af_spec_inet6_types[IFLA_INET6_MAX + 1] = { IFLA_INET6_CACHEINFO, IFLA_INET6_ICMP6STATS, */ - [IFLA_INET6_TOKEN] = { .type = NLA_IN_ADDR }, - [IFLA_INET6_ADDR_GEN_MODE] = { .type = NLA_U8 }, + [IFLA_INET6_TOKEN] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFLA_INET6_ADDR_GEN_MODE] = { .type = NETLINK_TYPE_U8 }, }; static const NLTypeSystem rtnl_af_spec_inet6_type_system = { - .max = ELEMENTSOF(rtnl_af_spec_inet6_types) - 1, + .count = ELEMENTSOF(rtnl_af_spec_inet6_types), .types = rtnl_af_spec_inet6_types, }; static const NLType rtnl_af_spec_types[AF_MAX + 1] = { - [AF_INET6] = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_inet6_type_system }, + [AF_INET6] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_inet6_type_system }, }; static const NLTypeSystem rtnl_af_spec_type_system = { - .max = ELEMENTSOF(rtnl_af_spec_types) - 1, + .count = ELEMENTSOF(rtnl_af_spec_types), .types = rtnl_af_spec_types, }; static const NLType rtnl_link_types[IFLA_MAX + 1 ] = { - [IFLA_ADDRESS] = { .type = NLA_ETHER_ADDR, }, - [IFLA_BROADCAST] = { .type = NLA_ETHER_ADDR, }, - [IFLA_IFNAME] = { .type = NLA_STRING, .size = IFNAMSIZ - 1, }, - [IFLA_MTU] = { .type = NLA_U32 }, - [IFLA_LINK] = { .type = NLA_U32 }, + [IFLA_ADDRESS] = { .type = NETLINK_TYPE_ETHER_ADDR, }, + [IFLA_BROADCAST] = { .type = NETLINK_TYPE_ETHER_ADDR, }, + [IFLA_IFNAME] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1, }, + [IFLA_MTU] = { .type = NETLINK_TYPE_U32 }, + [IFLA_LINK] = { .type = NETLINK_TYPE_U32 }, /* [IFLA_QDISC], [IFLA_STATS], [IFLA_COST], [IFLA_PRIORITY], */ - [IFLA_MASTER] = { .type = NLA_U32 }, + [IFLA_MASTER] = { .type = NETLINK_TYPE_U32 }, /* [IFLA_WIRELESS], */ - [IFLA_PROTINFO] = { .type = NLA_UNION, .type_system_union = &rtnl_prot_info_type_system_union }, - [IFLA_TXQLEN] = { .type = NLA_U32 }, + [IFLA_PROTINFO] = { .type = NETLINK_TYPE_UNION, .type_system_union = &rtnl_prot_info_type_system_union }, + [IFLA_TXQLEN] = { .type = NETLINK_TYPE_U32 }, /* [IFLA_MAP] = { .len = sizeof(struct rtnl_link_ifmap) }, */ - [IFLA_WEIGHT] = { .type = NLA_U32 }, - [IFLA_OPERSTATE] = { .type = NLA_U8 }, - [IFLA_LINKMODE] = { .type = NLA_U8 }, - [IFLA_LINKINFO] = { .type = NLA_NESTED, .type_system = &rtnl_link_info_type_system }, - [IFLA_NET_NS_PID] = { .type = NLA_U32 }, - [IFLA_IFALIAS] = { .type = NLA_STRING, .size = IFALIASZ - 1 }, + [IFLA_WEIGHT] = { .type = NETLINK_TYPE_U32 }, + [IFLA_OPERSTATE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_LINKMODE] = { .type = NETLINK_TYPE_U8 }, + [IFLA_LINKINFO] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_info_type_system }, + [IFLA_NET_NS_PID] = { .type = NETLINK_TYPE_U32 }, + [IFLA_IFALIAS] = { .type = NETLINK_TYPE_STRING, .size = IFALIASZ - 1 }, /* [IFLA_NUM_VF], - [IFLA_VFINFO_LIST] = {. type = NLA_NESTED, }, + [IFLA_VFINFO_LIST] = {. type = NETLINK_TYPE_NESTED, }, [IFLA_STATS64], - [IFLA_VF_PORTS] = { .type = NLA_NESTED }, - [IFLA_PORT_SELF] = { .type = NLA_NESTED }, + [IFLA_VF_PORTS] = { .type = NETLINK_TYPE_NESTED }, + [IFLA_PORT_SELF] = { .type = NETLINK_TYPE_NESTED }, */ - [IFLA_AF_SPEC] = { .type = NLA_NESTED, .type_system = &rtnl_af_spec_type_system }, + [IFLA_AF_SPEC] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_af_spec_type_system }, /* [IFLA_VF_PORTS], [IFLA_PORT_SELF], [IFLA_AF_SPEC], */ - [IFLA_GROUP] = { .type = NLA_U32 }, - [IFLA_NET_NS_FD] = { .type = NLA_U32 }, - [IFLA_EXT_MASK] = { .type = NLA_U32 }, - [IFLA_PROMISCUITY] = { .type = NLA_U32 }, - [IFLA_NUM_TX_QUEUES] = { .type = NLA_U32 }, - [IFLA_NUM_RX_QUEUES] = { .type = NLA_U32 }, - [IFLA_CARRIER] = { .type = NLA_U8 }, + [IFLA_GROUP] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NET_NS_FD] = { .type = NETLINK_TYPE_U32 }, + [IFLA_EXT_MASK] = { .type = NETLINK_TYPE_U32 }, + [IFLA_PROMISCUITY] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NUM_TX_QUEUES] = { .type = NETLINK_TYPE_U32 }, + [IFLA_NUM_RX_QUEUES] = { .type = NETLINK_TYPE_U32 }, + [IFLA_CARRIER] = { .type = NETLINK_TYPE_U8 }, /* - [IFLA_PHYS_PORT_ID] = { .type = NLA_BINARY, .len = MAX_PHYS_PORT_ID_LEN }, + [IFLA_PHYS_PORT_ID] = { .type = NETLINK_TYPE_BINARY, .len = MAX_PHYS_PORT_ID_LEN }, */ }; static const NLTypeSystem rtnl_link_type_system = { - .max = ELEMENTSOF(rtnl_link_types) - 1, + .count = ELEMENTSOF(rtnl_link_types), .types = rtnl_link_types, }; /* IFA_FLAGS was defined in kernel 3.14, but we still support older * kernels where IFA_MAX is lower. */ static const NLType rtnl_address_types[CONST_MAX(IFA_MAX, IFA_FLAGS) + 1] = { - [IFA_ADDRESS] = { .type = NLA_IN_ADDR }, - [IFA_LOCAL] = { .type = NLA_IN_ADDR }, - [IFA_LABEL] = { .type = NLA_STRING, .size = IFNAMSIZ - 1 }, - [IFA_BROADCAST] = { .type = NLA_IN_ADDR }, /* 6? */ - [IFA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) }, + [IFA_ADDRESS] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFA_LOCAL] = { .type = NETLINK_TYPE_IN_ADDR }, + [IFA_LABEL] = { .type = NETLINK_TYPE_STRING, .size = IFNAMSIZ - 1 }, + [IFA_BROADCAST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ + [IFA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct ifa_cacheinfo) }, /* [IFA_ANYCAST], [IFA_MULTICAST], */ - [IFA_FLAGS] = { .type = NLA_U32 }, + [IFA_FLAGS] = { .type = NETLINK_TYPE_U32 }, }; static const NLTypeSystem rtnl_address_type_system = { - .max = ELEMENTSOF(rtnl_address_types) - 1, + .count = ELEMENTSOF(rtnl_address_types), .types = rtnl_address_types, }; static const NLType rtnl_route_types[RTA_MAX + 1] = { - [RTA_DST] = { .type = NLA_IN_ADDR }, /* 6? */ - [RTA_SRC] = { .type = NLA_IN_ADDR }, /* 6? */ - [RTA_IIF] = { .type = NLA_U32 }, - [RTA_OIF] = { .type = NLA_U32 }, - [RTA_GATEWAY] = { .type = NLA_IN_ADDR }, - [RTA_PRIORITY] = { .type = NLA_U32 }, - [RTA_PREFSRC] = { .type = NLA_IN_ADDR }, /* 6? */ + [RTA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ + [RTA_SRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ + [RTA_IIF] = { .type = NETLINK_TYPE_U32 }, + [RTA_OIF] = { .type = NETLINK_TYPE_U32 }, + [RTA_GATEWAY] = { .type = NETLINK_TYPE_IN_ADDR }, + [RTA_PRIORITY] = { .type = NETLINK_TYPE_U32 }, + [RTA_PREFSRC] = { .type = NETLINK_TYPE_IN_ADDR }, /* 6? */ /* - [RTA_METRICS] = { .type = NLA_NESTED }, + [RTA_METRICS] = { .type = NETLINK_TYPE_NESTED }, [RTA_MULTIPATH] = { .len = sizeof(struct rtnexthop) }, */ - [RTA_FLOW] = { .type = NLA_U32 }, /* 6? */ + [RTA_FLOW] = { .type = NETLINK_TYPE_U32 }, /* 6? */ /* RTA_CACHEINFO, RTA_TABLE, @@ -417,65 +460,95 @@ static const NLType rtnl_route_types[RTA_MAX + 1] = { }; static const NLTypeSystem rtnl_route_type_system = { - .max = ELEMENTSOF(rtnl_route_types) - 1, + .count = ELEMENTSOF(rtnl_route_types), .types = rtnl_route_types, }; static const NLType rtnl_neigh_types[NDA_MAX + 1] = { - [NDA_DST] = { .type = NLA_IN_ADDR }, - [NDA_LLADDR] = { .type = NLA_ETHER_ADDR }, - [NDA_CACHEINFO] = { .type = NLA_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) }, - [NDA_PROBES] = { .type = NLA_U32 }, - [NDA_VLAN] = { .type = NLA_U16 }, - [NDA_PORT] = { .type = NLA_U16 }, - [NDA_VNI] = { .type = NLA_U32 }, - [NDA_IFINDEX] = { .type = NLA_U32 }, + [NDA_DST] = { .type = NETLINK_TYPE_IN_ADDR }, + [NDA_LLADDR] = { .type = NETLINK_TYPE_ETHER_ADDR }, + [NDA_CACHEINFO] = { .type = NETLINK_TYPE_CACHE_INFO, .size = sizeof(struct nda_cacheinfo) }, + [NDA_PROBES] = { .type = NETLINK_TYPE_U32 }, + [NDA_VLAN] = { .type = NETLINK_TYPE_U16 }, + [NDA_PORT] = { .type = NETLINK_TYPE_U16 }, + [NDA_VNI] = { .type = NETLINK_TYPE_U32 }, + [NDA_IFINDEX] = { .type = NETLINK_TYPE_U32 }, }; static const NLTypeSystem rtnl_neigh_type_system = { - .max = ELEMENTSOF(rtnl_neigh_types) - 1, + .count = ELEMENTSOF(rtnl_neigh_types), .types = rtnl_neigh_types, }; static const NLType rtnl_types[RTM_MAX + 1] = { - [NLMSG_DONE] = { .type = NLA_META, .size = 0 }, - [NLMSG_ERROR] = { .type = NLA_META, .size = sizeof(struct nlmsgerr) }, - [RTM_NEWLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_DELLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_GETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_SETLINK] = { .type = NLA_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, - [RTM_NEWADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_DELADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_GETADDR] = { .type = NLA_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, - [RTM_NEWROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_DELROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_GETROUTE] = { .type = NLA_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, - [RTM_NEWNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, - [RTM_DELNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, - [RTM_GETNEIGH] = { .type = NLA_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, -}; - -const NLTypeSystem rtnl_type_system = { - .max = ELEMENTSOF(rtnl_types) - 1, + [NLMSG_DONE] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = 0 }, + [NLMSG_ERROR] = { .type = NETLINK_TYPE_NESTED, .type_system = &empty_type_system, .size = sizeof(struct nlmsgerr) }, + [RTM_NEWLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_DELLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_GETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_SETLINK] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_link_type_system, .size = sizeof(struct ifinfomsg) }, + [RTM_NEWADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_DELADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_GETADDR] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_address_type_system, .size = sizeof(struct ifaddrmsg) }, + [RTM_NEWROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_DELROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_GETROUTE] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_route_type_system, .size = sizeof(struct rtmsg) }, + [RTM_NEWNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, + [RTM_DELNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, + [RTM_GETNEIGH] = { .type = NETLINK_TYPE_NESTED, .type_system = &rtnl_neigh_type_system, .size = sizeof(struct ndmsg) }, +}; + +const NLTypeSystem type_system_root = { + .count = ELEMENTSOF(rtnl_types), .types = rtnl_types, }; -int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { - const NLType *nl_type; +uint16_t type_get_type(const NLType *type) { + assert(type); + return type->type; +} +size_t type_get_size(const NLType *type) { + assert(type); + return type->size; +} + +void type_get_type_system(const NLType *nl_type, const NLTypeSystem **ret) { + assert(nl_type); assert(ret); + assert(nl_type->type == NETLINK_TYPE_NESTED); + assert(nl_type->type_system); - if (!type_system) - type_system = &rtnl_type_system; + *ret = nl_type->type_system; +} +void type_get_type_system_union(const NLType *nl_type, const NLTypeSystemUnion **ret) { + assert(nl_type); + assert(ret); + assert(nl_type->type == NETLINK_TYPE_UNION); + assert(nl_type->type_system_union); + + *ret = nl_type->type_system_union; +} + +uint16_t type_system_get_count(const NLTypeSystem *type_system) { + assert(type_system); + return type_system->count; +} + +int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type) { + const NLType *nl_type; + + assert(ret); + assert(type_system); assert(type_system->types); - if (type > type_system->max) + if (type >= type_system->count) return -EOPNOTSUPP; nl_type = &type_system->types[type]; - if (nl_type->type == NLA_UNSPEC) + if (nl_type->type == NETLINK_TYPE_UNSPEC) return -EOPNOTSUPP; *ret = nl_type; @@ -493,11 +566,7 @@ int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSys if (r < 0) return r; - assert(nl_type->type == NLA_NESTED); - assert(nl_type->type_system); - - *ret = nl_type->type_system; - + type_get_type_system(nl_type, ret); return 0; } @@ -511,11 +580,7 @@ int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLT if (r < 0) return r; - assert(nl_type->type == NLA_UNION); - assert(nl_type->type_system_union); - - *ret = nl_type->type_system_union; - + type_get_type_system_union(nl_type, ret); return 0; } @@ -552,7 +617,7 @@ int type_system_union_protocol_get_type_system(const NLTypeSystemUnion *type_sys return -EOPNOTSUPP; type_system = &type_system_union->type_systems[protocol]; - if (type_system->max == 0) + if (!type_system->types) return -EOPNOTSUPP; *ret = type_system; diff --git a/src/libsystemd/sd-netlink/netlink-types.h b/src/libsystemd/sd-netlink/netlink-types.h index de1544bf36..a210163241 100644 --- a/src/libsystemd/sd-netlink/netlink-types.h +++ b/src/libsystemd/sd-netlink/netlink-types.h @@ -22,18 +22,17 @@ ***/ enum { - NLA_UNSPEC, - NLA_META, - NLA_U8, - NLA_U16, - NLA_U32, - NLA_U64, - NLA_STRING, - NLA_IN_ADDR, - NLA_ETHER_ADDR, - NLA_CACHE_INFO, - NLA_NESTED, - NLA_UNION, + NETLINK_TYPE_UNSPEC, + NETLINK_TYPE_U8, /* NLA_U8 */ + NETLINK_TYPE_U16, /* NLA_U16 */ + NETLINK_TYPE_U32, /* NLA_U32 */ + NETLINK_TYPE_U64, /* NLA_U64 */ + NETLINK_TYPE_STRING, /* NLA_STRING */ + NETLINK_TYPE_IN_ADDR, + NETLINK_TYPE_ETHER_ADDR, + NETLINK_TYPE_CACHE_INFO, + NETLINK_TYPE_NESTED, /* NLA_NESTED */ + NETLINK_TYPE_UNION, }; typedef enum NLMatchType { @@ -53,18 +52,14 @@ struct NLTypeSystemUnion { const NLTypeSystem *type_systems; }; -struct NLTypeSystem { - uint16_t max; - const NLType *types; -}; +extern const NLTypeSystem type_system_root; -struct NLType { - uint16_t type; - size_t size; - const NLTypeSystem *type_system; - const NLTypeSystemUnion *type_system_union; -}; +uint16_t type_get_type(const NLType *type); +size_t type_get_size(const NLType *type); +void type_get_type_system(const NLType *type, const NLTypeSystem **ret); +void type_get_type_system_union(const NLType *type, const NLTypeSystemUnion **ret); +uint16_t type_system_get_count(const NLTypeSystem *type_system); int type_system_get_type(const NLTypeSystem *type_system, const NLType **ret, uint16_t type); int type_system_get_type_system(const NLTypeSystem *type_system, const NLTypeSystem **ret, uint16_t type); int type_system_get_type_system_union(const NLTypeSystem *type_system, const NLTypeSystemUnion **ret, uint16_t type); @@ -95,25 +90,3 @@ typedef enum NLUnionLinkInfoData { const char *nl_union_link_info_data_to_string(NLUnionLinkInfoData p) _const_; NLUnionLinkInfoData nl_union_link_info_data_from_string(const char *p) _pure_; - -/* Maximum ARP IP target defined in kernel */ -#define BOND_MAX_ARP_TARGETS 16 - -typedef enum BondArpTargets { - BOND_ARP_TARGETS_0, - BOND_ARP_TARGETS_1, - BOND_ARP_TARGETS_2, - BOND_ARP_TARGETS_3, - BOND_ARP_TARGETS_4, - BOND_ARP_TARGETS_5, - BOND_ARP_TARGETS_6, - BOND_ARP_TARGETS_7, - BOND_ARP_TARGETS_8, - BOND_ARP_TARGETS_9, - BOND_ARP_TARGETS_10, - BOND_ARP_TARGETS_11, - BOND_ARP_TARGETS_12, - BOND_ARP_TARGETS_13, - BOND_ARP_TARGETS_14, - BOND_ARP_TARGETS_MAX = BOND_MAX_ARP_TARGETS, -} BondArpTargets; diff --git a/src/libsystemd/sd-network/Makefile b/src/libsystemd/sd-network/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/libsystemd/sd-network/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-path/Makefile b/src/libsystemd/sd-path/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/libsystemd/sd-path/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-resolve/Makefile b/src/libsystemd/sd-resolve/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/src/libsystemd/sd-resolve/Makefile @@ -0,0 +1 @@ +../../Makefile
\ No newline at end of file diff --git a/src/libsystemd/sd-utf8/Makefile b/src/libsystemd/sd-utf8/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/src/libsystemd/sd-utf8/Makefile @@ -0,0 +1 @@ +../../Makefile
\ No newline at end of file diff --git a/src/libudev/.gitignore b/src/libudev/.gitignore new file mode 100644 index 0000000000..0c8a5d5231 --- /dev/null +++ b/src/libudev/.gitignore @@ -0,0 +1 @@ +/libudev.pc diff --git a/src/libudev/Makefile b/src/libudev/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/libudev/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/locale/.gitignore b/src/locale/.gitignore new file mode 100644 index 0000000000..b1e0ba755e --- /dev/null +++ b/src/locale/.gitignore @@ -0,0 +1 @@ +org.freedesktop.locale1.policy diff --git a/src/locale/Makefile b/src/locale/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/locale/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/locale/localectl.c b/src/locale/localectl.c index 601839d5dc..3616f4af1f 100644 --- a/src/locale/localectl.c +++ b/src/locale/localectl.c @@ -667,7 +667,7 @@ static int localectl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char*argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); diff --git a/src/locale/localed.c b/src/locale/localed.c index 0e59350e98..88756542fd 100644 --- a/src/locale/localed.c +++ b/src/locale/localed.c @@ -1240,7 +1240,7 @@ static const sd_bus_vtable locale_vtable[] = { }; static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; assert(c); @@ -1272,7 +1272,7 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { int main(int argc, char *argv[]) { _cleanup_(context_free) Context context = {}; _cleanup_event_unref_ sd_event *event = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; log_set_target(LOG_TARGET_AUTO); diff --git a/src/login/.gitignore b/src/login/.gitignore new file mode 100644 index 0000000000..5c0b2ac68c --- /dev/null +++ b/src/login/.gitignore @@ -0,0 +1,4 @@ +/logind-gperf.c +/org.freedesktop.login1.policy +/71-seat.rules +/73-seat-late.rules diff --git a/src/login/71-seat.rules.in b/src/login/71-seat.rules.in index ab7b66f651..de55c9a4ec 100644 --- a/src/login/71-seat.rules.in +++ b/src/login/71-seat.rules.in @@ -17,6 +17,11 @@ SUBSYSTEM=="usb", ATTR{bDeviceClass}=="09", TAG+="seat" # 'Plugable' USB hub, sound, network, graphics adapter SUBSYSTEM=="usb", ATTR{idVendor}=="2230", ATTR{idProduct}=="000[13]", ENV{ID_AUTOSEAT}="1" +# qemu (version 2.4+) has a PCI-PCI bridge (-device pci-bridge-seat) to group +# devices belonging to one seat. See: +# http://git.qemu.org/?p=qemu.git;a=blob;f=docs/multiseat.txt +SUBSYSTEM=="pci", ATTR{vendor}=="0x1b36", ATTR{device}=="0x000a", TAG+="seat", ENV{ID_AUTOSEAT}="1" + # Mimo 720, with integrated USB hub, displaylink graphics, and e2i # touchscreen. This device carries no proper VID/PID in the USB hub, # but it does carry good ID data in the graphics component, hence we diff --git a/src/login/Makefile b/src/login/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/login/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/login/inhibit.c b/src/login/inhibit.c index 0e5dce5925..c53ea8add7 100644 --- a/src/login/inhibit.c +++ b/src/login/inhibit.c @@ -223,7 +223,7 @@ static int parse_argv(int argc, char *argv[]) { int main(int argc, char *argv[]) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; log_parse_environment(); diff --git a/src/login/loginctl.c b/src/login/loginctl.c index 06208bc4b3..9709eca9bd 100644 --- a/src/login/loginctl.c +++ b/src/login/loginctl.c @@ -1389,7 +1389,7 @@ static int loginctl_main(int argc, char *argv[], sd_bus *bus) { } int main(int argc, char *argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); diff --git a/src/login/logind-core.c b/src/login/logind-core.c index a6c01f7d85..96a20e27b9 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -317,7 +317,6 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { int r; assert(m); - assert(session); if (pid < 1) return -EINVAL; @@ -330,7 +329,8 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) { if (!s) return 0; - *session = s; + if (session) + *session = s; return 1; } diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 8ebcd3f5ca..82654ee8c7 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -689,45 +689,23 @@ static int method_create_session(sd_bus_message *message, void *userdata, sd_bus return r; } - manager_get_session_by_pid(m, leader, &session); - if (session) { - _cleanup_free_ char *path = NULL; - _cleanup_close_ int fifo_fd = -1; - - /* Session already exists, client is probably - * something like "su" which changes uid but is still - * the same session */ - - fifo_fd = session_create_fifo(session); - if (fifo_fd < 0) - return fifo_fd; - - path = session_bus_path(session); - if (!path) - return -ENOMEM; - - log_debug("Sending reply about an existing session: " - "id=%s object_path=%s uid=%u runtime_path=%s " - "session_fd=%d seat=%s vtnr=%u", - session->id, - path, - (uint32_t) session->user->uid, - session->user->runtime_path, - fifo_fd, - session->seat ? session->seat->id : "", - (uint32_t) session->vtnr); - - return sd_bus_reply_method_return( - message, "soshusub", - session->id, - path, - session->user->runtime_path, - fifo_fd, - (uint32_t) session->user->uid, - session->seat ? session->seat->id : "", - (uint32_t) session->vtnr, - true); - } + r = manager_get_session_by_pid(m, leader, NULL); + if (r > 0) + return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already running in a session"); + + /* + * Old gdm and lightdm start the user-session on the same VT as + * the greeter session. But they destroy the greeter session + * after the user-session and want the user-session to take + * over the VT. We need to support this for + * backwards-compatibility, so make sure we allow new sessions + * on a VT that a greeter is running on. + */ + if (vtnr > 0 && + vtnr < m->seat0->position_count && + m->seat0->positions[vtnr] && + m->seat0->positions[vtnr]->class != SESSION_GREETER) + return sd_bus_error_setf(error, BUS_ERROR_SESSION_BUSY, "Already occupied by a session"); audit_session_from_pid(leader, &audit_id); if (audit_id > 0) { @@ -1486,18 +1464,13 @@ static int execute_shutdown_or_sleep( return 0; } -static int manager_inhibit_timeout_handler( - sd_event_source *s, - uint64_t usec, - void *userdata) { +int manager_dispatch_delayed(Manager *manager, bool timeout) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; Inhibitor *offending = NULL; - Manager *manager = userdata; int r; assert(manager); - assert(manager->inhibit_timeout_source == s); if (manager->action_what == 0 || manager->action_job) return 0; @@ -1505,6 +1478,9 @@ static int manager_inhibit_timeout_handler( if (manager_is_inhibited(manager, manager->action_what, INHIBIT_DELAY, NULL, false, false, 0, &offending)) { _cleanup_free_ char *comm = NULL, *u = NULL; + if (!timeout) + return 0; + (void) get_process_comm(offending->pid, &comm); u = uid_to_name(offending->uid); @@ -1520,9 +1496,25 @@ static int manager_inhibit_timeout_handler( manager->action_unit = NULL; manager->action_what = 0; + return r; } - return 0; + return 1; +} + +static int manager_inhibit_timeout_handler( + sd_event_source *s, + uint64_t usec, + void *userdata) { + + Manager *manager = userdata; + int r; + + assert(manager); + assert(manager->inhibit_timeout_source == s); + + r = manager_dispatch_delayed(manager, true); + return (r < 0) ? r : 0; } static int delay_shutdown_or_sleep( diff --git a/src/login/logind-seat.c b/src/login/logind-seat.c index 3c30eeaa95..fb5d076311 100644 --- a/src/login/logind-seat.c +++ b/src/login/logind-seat.c @@ -269,7 +269,7 @@ int seat_set_active(Seat *s, Session *session) { int seat_switch_to(Seat *s, unsigned int num) { /* Public session positions skip 0 (there is only F1-F12). Maybe it * will get reassigned in the future, so return error for now. */ - if (!num) + if (num == 0) return -EINVAL; if (num >= s->position_count || !s->positions[num]) { @@ -286,7 +286,7 @@ int seat_switch_to(Seat *s, unsigned int num) { int seat_switch_to_next(Seat *s) { unsigned int start, i; - if (!s->position_count) + if (s->position_count == 0) return -EINVAL; start = 1; @@ -307,7 +307,7 @@ int seat_switch_to_next(Seat *s) { int seat_switch_to_previous(Seat *s) { unsigned int start, i; - if (!s->position_count) + if (s->position_count == 0) return -EINVAL; start = 1; @@ -476,14 +476,14 @@ void seat_evict_position(Seat *s, Session *session) { session->pos = 0; - if (!pos) + if (pos == 0) return; if (pos < s->position_count && s->positions[pos] == session) { s->positions[pos] = NULL; /* There might be another session claiming the same - * position (eg., during gdm->session transition), so lets look + * position (eg., during gdm->session transition), so let's look * for it and set it on the free slot. */ LIST_FOREACH(sessions_by_seat, iter, s->sessions) { if (iter->pos == pos) { diff --git a/src/login/logind.c b/src/login/logind.c index 01f7cd9ee0..e2fb496289 100644 --- a/src/login/logind.c +++ b/src/login/logind.c @@ -1109,6 +1109,12 @@ static int manager_run(Manager *m) { manager_gc(m, true); + r = manager_dispatch_delayed(m, false); + if (r < 0) + return r; + if (r > 0) + continue; + r = sd_event_run(m->event, (uint64_t) -1); if (r < 0) return r; diff --git a/src/login/logind.h b/src/login/logind.h index feb381d0b1..ad437b72cb 100644 --- a/src/login/logind.h +++ b/src/login/logind.h @@ -194,3 +194,5 @@ int manager_get_seat_from_creds(Manager *m, sd_bus_message *message, const char int manager_setup_wall_message_timer(Manager *m); bool logind_wall_tty_filter(const char *tty, void *userdata); + +int manager_dispatch_delayed(Manager *manager, bool timeout); diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index 0ebdfdf19e..f83d18b035 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -31,6 +31,7 @@ #include <security/pam_ext.h> #include <security/pam_misc.h> +#include "bus-common-errors.h" #include "util.h" #include "audit.h" #include "macro.h" @@ -181,7 +182,7 @@ static int export_legacy_dbus_address( int r; /* skip export if kdbus is not active */ - if (access("/sys/fs/kdbus", F_OK) < 0) + if (!is_kdbus_available()) return PAM_SUCCESS; if (asprintf(&s, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, uid, runtime) < 0) { @@ -213,7 +214,7 @@ _public_ PAM_EXTERN int pam_sm_open_session( *seat = NULL, *type = NULL, *class = NULL, *class_pam = NULL, *type_pam = NULL, *cvtnr = NULL, *desktop = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int session_fd = -1, existing, r; bool debug = false, remote; struct passwd *pw; @@ -399,8 +400,13 @@ _public_ PAM_EXTERN int pam_sm_open_session( remote_host, 0); if (r < 0) { - pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error, r)); - return PAM_SYSTEM_ERR; + if (sd_bus_error_has_name(&error, BUS_ERROR_SESSION_BUSY)) { + pam_syslog(handle, LOG_DEBUG, "Cannot create session: %s", bus_error_message(&error, r)); + return PAM_SUCCESS; + } else { + pam_syslog(handle, LOG_ERR, "Failed to create session: %s", bus_error_message(&error, r)); + return PAM_SYSTEM_ERR; + } } r = sd_bus_message_read(reply, @@ -496,7 +502,7 @@ _public_ PAM_EXTERN int pam_sm_close_session( int argc, const char **argv) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; const void *existing = NULL; const char *id; int r; diff --git a/src/machine-id-commit/Makefile b/src/machine-id-commit/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/machine-id-commit/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/machine-id-setup/Makefile b/src/machine-id-setup/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/machine-id-setup/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/machine/.gitignore b/src/machine/.gitignore new file mode 100644 index 0000000000..e1065b5894 --- /dev/null +++ b/src/machine/.gitignore @@ -0,0 +1 @@ +/org.freedesktop.machine1.policy diff --git a/src/machine/Makefile b/src/machine/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/machine/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c index 7938aa4dbe..7cb6ce77ac 100644 --- a/src/machine/machinectl.c +++ b/src/machine/machinectl.c @@ -2572,7 +2572,7 @@ static int machinectl_main(int argc, char *argv[], sd_bus *bus) { } int main(int argc, char*argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); diff --git a/src/modules-load/Makefile b/src/modules-load/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/modules-load/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/network/.gitignore b/src/network/.gitignore new file mode 100644 index 0000000000..8858596489 --- /dev/null +++ b/src/network/.gitignore @@ -0,0 +1,2 @@ +/networkd-network-gperf.c +/networkd-netdev-gperf.c diff --git a/src/network/Makefile b/src/network/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/network/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 16243a5352..5607cf470e 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -116,6 +116,16 @@ static bool link_ipv6_forward_enabled(Link *link) { return link->network->ip_forward & ADDRESS_FAMILY_IPV6; } +static IPv6PrivacyExtensions link_ipv6_privacy_extensions(Link *link) { + if (link->flags & IFF_LOOPBACK) + return _IPV6_PRIVACY_EXTENSIONS_INVALID; + + if (!link->network) + return _IPV6_PRIVACY_EXTENSIONS_INVALID; + + return link->network->ipv6_privacy_extensions; +} + #define FLAG_STRING(string, flag, old, new) \ (((old ^ new) & flag) \ ? ((old & flag) ? (" -" string) : (" +" string)) \ @@ -1360,8 +1370,7 @@ static int link_joined(Link *link) { return link_enter_set_addresses(link); } -static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, - void *userdata) { +static int netdev_join_handler(sd_netlink *rtnl, sd_netlink_message *m, void *userdata) { _cleanup_link_unref_ Link *link = userdata; int r; @@ -1474,35 +1483,84 @@ static int link_enter_join_netdev(Link *link) { } static int link_set_ipv4_forward(Link *link) { - const char *p = NULL; + const char *p = NULL, *v; int r; + if (link->flags & IFF_LOOPBACK) + return 0; + if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID) return 0; p = strjoina("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding"); - r = write_string_file_no_create(p, one_zero(link_ipv4_forward_enabled(link))); - if (r < 0) + v = one_zero(link_ipv4_forward_enabled(link)); + + r = write_string_file_no_create(p, v); + if (r < 0) { + /* If the right value is set anyway, don't complain */ + if (verify_one_line_file(p, v) > 0) + return 0; + log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface %s: %m", link->ifname); + } return 0; } static int link_set_ipv6_forward(Link *link) { - const char *p = NULL; + const char *p = NULL, *v = NULL; int r; /* Make this a NOP if IPv6 is not available */ if (!socket_ipv6_is_supported()) return 0; + if (link->flags & IFF_LOOPBACK) + return 0; + if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID) return 0; p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding"); - r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link))); - if (r < 0) + v = one_zero(link_ipv6_forward_enabled(link)); + + r = write_string_file_no_create(p, v); + if (r < 0) { + /* If the right value is set anyway, don't complain */ + if (verify_one_line_file(p, v) > 0) + return 0; + log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m"); + } + + return 0; +} + +static int link_set_ipv6_privacy_extensions(Link *link) { + char buf[DECIMAL_STR_MAX(unsigned) + 1]; + IPv6PrivacyExtensions s; + const char *p = NULL; + int r; + + /* Make this a NOP if IPv6 is not available */ + if (!socket_ipv6_is_supported()) + return 0; + + s = link_ipv6_privacy_extensions(link); + if (s == _IPV6_PRIVACY_EXTENSIONS_INVALID) + return 0; + + p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr"); + xsprintf(buf, "%u", link->network->ipv6_privacy_extensions); + + r = write_string_file_no_create(p, buf); + if (r < 0) { + /* If the right value is set anyway, don't complain */ + if (verify_one_line_file(p, buf) > 0) + return 0; + + log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m"); + } return 0; } @@ -1526,6 +1584,10 @@ static int link_configure(Link *link) { if (r < 0) return r; + r = link_set_ipv6_privacy_extensions(link); + if (r < 0) + return r; + if (link_ipv4ll_enabled(link)) { r = ipv4ll_configure(link); if (r < 0) diff --git a/src/network/networkd-netdev-bond.c b/src/network/networkd-netdev-bond.c index 6336ff58a7..a60034dbe6 100644 --- a/src/network/networkd-netdev-bond.c +++ b/src/network/networkd-netdev-bond.c @@ -25,7 +25,6 @@ #include "conf-parser.h" #include "sd-netlink.h" -#include "netlink-types.h" #include "networkd-netdev-bond.h" #include "missing.h" @@ -372,11 +371,11 @@ int config_parse_arp_ip_target_address(const char *unit, b->n_arp_ip_targets ++; buffer = NULL; - - if (b->n_arp_ip_targets > BOND_ARP_TARGETS_MAX) - break; } + if (b->n_arp_ip_targets > NETDEV_BOND_ARP_TARGETS_MAX) + log_syntax(unit, LOG_WARNING, filename, line, EINVAL, "More than the maximum number of kernel-supported ARP ip targets specified: %d > %d", b->n_arp_ip_targets, NETDEV_BOND_ARP_TARGETS_MAX); + return 0; } diff --git a/src/network/networkd-netdev-bond.h b/src/network/networkd-netdev-bond.h index 32d1702d58..9991fa731f 100644 --- a/src/network/networkd-netdev-bond.h +++ b/src/network/networkd-netdev-bond.h @@ -25,6 +25,12 @@ typedef struct Bond Bond; #include "networkd-netdev.h" +/* + * Maximum number of targets supported by the kernel for a single + * bond netdev. + */ +#define NETDEV_BOND_ARP_TARGETS_MAX 16 + typedef enum BondMode { NETDEV_BOND_MODE_BALANCE_RR, NETDEV_BOND_MODE_ACTIVE_BACKUP, diff --git a/src/network/networkd-netdev.c b/src/network/networkd-netdev.c index ece9ecc251..6949b403c8 100644 --- a/src/network/networkd-netdev.c +++ b/src/network/networkd-netdev.c @@ -92,10 +92,11 @@ static void netdev_cancel_callbacks(NetDev *netdev) { assert(netdev->manager); assert(netdev->manager->rtnl); - callback->callback(netdev->manager->rtnl, m, link); + callback->callback(netdev->manager->rtnl, m, callback->link); } LIST_REMOVE(callbacks, netdev->callbacks, callback); + link_unref(callback->link); free(callback); } } @@ -177,6 +178,8 @@ int netdev_get(Manager *manager, const char *name, NetDev **ret) { static int netdev_enter_failed(NetDev *netdev) { netdev->state = NETDEV_STATE_FAILED; + netdev_cancel_callbacks(netdev); + return 0; } @@ -266,12 +269,20 @@ int netdev_enslave(NetDev *netdev, Link *link, sd_netlink_message_handler_t call int r; assert(netdev); + assert(netdev->manager); + assert(netdev->manager->rtnl); assert(IN_SET(netdev->kind, NETDEV_KIND_BRIDGE, NETDEV_KIND_BOND)); if (netdev->state == NETDEV_STATE_READY) { r = netdev_enslave_ready(netdev, link, callback); if (r < 0) return r; + } else if (IN_SET(netdev->state, NETDEV_STATE_LINGER, NETDEV_STATE_FAILED)) { + _cleanup_netlink_message_unref_ sd_netlink_message *m = NULL; + + r = rtnl_message_new_synthetic_error(-ENODEV, 0, &m); + if (r >= 0) + callback(netdev->manager->rtnl, m, link); } else { /* the netdev is not yet read, save this request for when it is */ netdev_join_callback *cb; diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index b05bc949f2..787fc2ff5b 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -15,69 +15,70 @@ struct ConfigPerfItem; %struct-type %includes %% -Match.MACAddress, config_parse_hwaddr, 0, offsetof(Network, match_mac) -Match.Path, config_parse_strv, 0, offsetof(Network, match_path) -Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver) -Match.Type, config_parse_strv, 0, offsetof(Network, match_type) -Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name) -Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) -Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel) -Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch) -Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac) -Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu) -Network.Description, config_parse_string, 0, offsetof(Network, description) -Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge) -Network.Bond, config_parse_netdev, 0, offsetof(Network, bond) -Network.VLAN, config_parse_netdev, 0, 0 -Network.MACVLAN, config_parse_netdev, 0, 0 -Network.IPVLAN, config_parse_netdev, 0, 0 -Network.VXLAN, config_parse_netdev, 0, 0 -Network.Tunnel, config_parse_tunnel, 0, 0 -Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp) -Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server) -Network.LinkLocalAddressing, config_parse_address_family_boolean, 0, offsetof(Network, link_local) -Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route) -Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token) -Network.LLDP, config_parse_bool, 0, offsetof(Network, lldp) -Network.Address, config_parse_address, 0, 0 -Network.Gateway, config_parse_gateway, 0, 0 -Network.Domains, config_parse_domains, 0, offsetof(Network, domains) -Network.DNS, config_parse_strv, 0, offsetof(Network, dns) -Network.LLMNR, config_parse_llmnr, 0, offsetof(Network, llmnr) -Network.NTP, config_parse_strv, 0, offsetof(Network, ntp) -Network.IPForward, config_parse_address_family_boolean_with_kernel,0, offsetof(Network, ip_forward) -Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade) -Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier) -Address.Address, config_parse_address, 0, 0 -Address.Peer, config_parse_address, 0, 0 -Address.Broadcast, config_parse_broadcast, 0, 0 -Address.Label, config_parse_label, 0, 0 -Route.Gateway, config_parse_gateway, 0, 0 -Route.Destination, config_parse_destination, 0, 0 -Route.Source, config_parse_destination, 0, 0 -Route.Metric, config_parse_route_priority, 0, 0 -Route.Scope, config_parse_route_scope, 0, 0 -DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) -DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) -DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_ntp) -DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) -DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) -DHCP.UseDomains, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes) -DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_sendhost) -DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) -DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) -DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) -DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) -Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost) -BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0 -BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0 +Match.MACAddress, config_parse_hwaddr, 0, offsetof(Network, match_mac) +Match.Path, config_parse_strv, 0, offsetof(Network, match_path) +Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver) +Match.Type, config_parse_strv, 0, offsetof(Network, match_type) +Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name) +Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) +Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt) +Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel) +Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch) +Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac) +Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu) +Network.Description, config_parse_string, 0, offsetof(Network, description) +Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge) +Network.Bond, config_parse_netdev, 0, offsetof(Network, bond) +Network.VLAN, config_parse_netdev, 0, 0 +Network.MACVLAN, config_parse_netdev, 0, 0 +Network.IPVLAN, config_parse_netdev, 0, 0 +Network.VXLAN, config_parse_netdev, 0, 0 +Network.Tunnel, config_parse_tunnel, 0, 0 +Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp) +Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server) +Network.LinkLocalAddressing, config_parse_address_family_boolean, 0, offsetof(Network, link_local) +Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route) +Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token) +Network.LLDP, config_parse_bool, 0, offsetof(Network, lldp) +Network.Address, config_parse_address, 0, 0 +Network.Gateway, config_parse_gateway, 0, 0 +Network.Domains, config_parse_domains, 0, offsetof(Network, domains) +Network.DNS, config_parse_strv, 0, offsetof(Network, dns) +Network.LLMNR, config_parse_llmnr, 0, offsetof(Network, llmnr) +Network.NTP, config_parse_strv, 0, offsetof(Network, ntp) +Network.IPForward, config_parse_address_family_boolean_with_kernel,0, offsetof(Network, ip_forward) +Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade) +Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions, 0, offsetof(Network, ipv6_privacy_extensions) +Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier) +Address.Address, config_parse_address, 0, 0 +Address.Peer, config_parse_address, 0, 0 +Address.Broadcast, config_parse_broadcast, 0, 0 +Address.Label, config_parse_label, 0, 0 +Route.Gateway, config_parse_gateway, 0, 0 +Route.Destination, config_parse_destination, 0, 0 +Route.Source, config_parse_destination, 0, 0 +Route.Metric, config_parse_route_priority, 0, 0 +Route.Scope, config_parse_route_scope, 0, 0 +DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) +DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) +DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_ntp) +DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) +DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) +DHCP.UseDomains, config_parse_bool, 0, offsetof(Network, dhcp_domains) +DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes) +DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_sendhost) +DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) +DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) +DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) +DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) +Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost) +BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0 +BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0 /* backwards compatibility: do not add new entries to this section */ -Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) -DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) -DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) -DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) -DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCPv4.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCPv4.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) +Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) +DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) +DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) +DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) +DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) +DHCPv4.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) +DHCPv4.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index ec95c8661e..a8e9ef909c 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -111,6 +111,8 @@ static int network_load_one(Manager *manager, const char *filename) { network->link_local = ADDRESS_FAMILY_IPV6; + network->ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO; + r = config_parse(NULL, filename, file, "Match\0" "Link\0" @@ -751,3 +753,59 @@ int config_parse_address_family_boolean_with_kernel( return 0; } + +static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = { + [IPV6_PRIVACY_EXTENSIONS_NO] = "no", + [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "prefer-public", + [IPV6_PRIVACY_EXTENSIONS_YES] = "yes", +}; + +DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions, IPv6PrivacyExtensions); + +int config_parse_ipv6_privacy_extensions( + const char* unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + IPv6PrivacyExtensions *ipv6_privacy_extensions = data; + int k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(ipv6_privacy_extensions); + + /* Our enum shall be a superset of booleans, hence first try + * to parse as boolean, and then as enum */ + + k = parse_boolean(rvalue); + if (k > 0) + *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_YES; + else if (k == 0) + *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO; + else { + IPv6PrivacyExtensions s; + + s = ipv6_privacy_extensions_from_string(rvalue); + if (s < 0) { + + if (streq(rvalue, "kernel")) + s = _IPV6_PRIVACY_EXTENSIONS_INVALID; + else { + log_syntax(unit, LOG_ERR, filename, line, s, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue); + return 0; + } + } + + *ipv6_privacy_extensions = s; + } + + return 0; +} diff --git a/src/network/networkd.c b/src/network/networkd.c index 9fe8a5fa15..e6259043fa 100644 --- a/src/network/networkd.c +++ b/src/network/networkd.c @@ -103,7 +103,7 @@ int main(int argc, char *argv[]) { r = manager_rtnl_enumerate_addresses(m); if (r < 0) { - log_error_errno(r, "Could not enumerate links: %m"); + log_error_errno(r, "Could not enumerate addresses: %m"); goto out; } diff --git a/src/network/networkd.h b/src/network/networkd.h index ac6e2c8a8e..f98c640822 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -90,6 +90,15 @@ typedef enum DCHPClientIdentifier { _DHCP_CLIENT_ID_INVALID = -1, } DCHPClientIdentifier; +typedef enum IPv6PrivacyExtensions { + /* The values map to the kernel's /proc/sys/net/ipv6/conf/xxx/use_tempaddr values */ + IPV6_PRIVACY_EXTENSIONS_NO, + IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC, + IPV6_PRIVACY_EXTENSIONS_YES, /* aka prefer-temporary */ + _IPV6_PRIVACY_EXTENSIONS_MAX, + _IPV6_PRIVACY_EXTENSIONS_INVALID = -1, +} IPv6PrivacyExtensions; + struct FdbEntry { Network *network; unsigned section; @@ -145,6 +154,8 @@ struct Network { AddressFamilyBoolean ip_forward; bool ip_masquerade; + IPv6PrivacyExtensions ipv6_privacy_extensions; + struct ether_addr *mac; unsigned mtu; @@ -455,3 +466,10 @@ int config_parse_address_family_boolean_with_kernel(const char *unit, const char const char* link_operstate_to_string(LinkOperationalState s) _const_; LinkOperationalState link_operstate_from_string(const char *s) _pure_; + +/* IPv6 privacy extensions support */ + +const char* ipv6_privacy_extensions_to_string(IPv6PrivacyExtensions i) _const_; +IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_; + +int config_parse_ipv6_privacy_extensions(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); diff --git a/src/notify/Makefile b/src/notify/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/notify/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/nspawn/Makefile b/src/nspawn/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/nspawn/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 4cf2d14ae2..198de3097d 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -341,6 +341,11 @@ static int custom_mounts_prepare(void) { for (i = 0; i < arg_n_custom_mounts; i++) { CustomMount *m = &arg_custom_mounts[i]; + if (arg_userns && arg_uid_shift == UID_INVALID && path_equal(m->destination, "/")) { + log_error("--private-users with automatic UID shift may not be combined with custom root mounts."); + return -EINVAL; + } + if (m->type != CUSTOM_MOUNT_OVERLAY) continue; @@ -751,9 +756,8 @@ static int parse_argv(int argc, char *argv[]) { /* If two parameters are specified, * the first one is the lower, the * second one the upper directory. And - * we'll also define the the - * destination mount point the same as - * the upper. */ + * we'll also define the destination + * mount point the same as the upper. */ upper = lower[1]; lower[1] = NULL; @@ -1028,6 +1032,7 @@ static int tmpfs_patch_options(const char *options, char **ret) { char *buf = NULL; if (arg_userns && arg_uid_shift != 0) { + assert(arg_uid_shift != UID_INVALID); if (options) (void) asprintf(&buf, "%s,uid=" UID_FMT ",gid=" UID_FMT, options, arg_uid_shift, arg_uid_shift); @@ -1074,18 +1079,18 @@ static int mount_all(const char *dest, bool userns) { } MountPoint; static const MountPoint mount_table[] = { - { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true, true }, - { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true, true }, /* Bind mount first */ - { NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, true, true }, /* Then, make it r/o */ - { "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true, false }, - { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, true, false }, - { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true, false }, - { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false }, - { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false }, - { "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_STRICTATIME, true, false }, + { "proc", "/proc", "proc", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV, true, true }, + { "/proc/sys", "/proc/sys", NULL, NULL, MS_BIND, true, true }, /* Bind mount first */ + { NULL, "/proc/sys", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, true, true }, /* Then, make it r/o */ + { "sysfs", "/sys", "sysfs", NULL, MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV, true, false }, + { "tmpfs", "/sys/fs/cgroup", "tmpfs", "mode=755", MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME, true, false }, + { "tmpfs", "/dev", "tmpfs", "mode=755", MS_NOSUID|MS_STRICTATIME, true, false }, + { "tmpfs", "/dev/shm", "tmpfs", "mode=1777", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false }, + { "tmpfs", "/run", "tmpfs", "mode=755", MS_NOSUID|MS_NODEV|MS_STRICTATIME, true, false }, + { "tmpfs", "/tmp", "tmpfs", "mode=1777", MS_STRICTATIME, true, false }, #ifdef HAVE_SELINUX - { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, false, false }, /* Bind mount first */ - { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, false, false }, /* Then, make it r/o */ + { "/sys/fs/selinux", "/sys/fs/selinux", NULL, NULL, MS_BIND, false, false }, /* Bind mount first */ + { NULL, "/sys/fs/selinux", NULL, NULL, MS_BIND|MS_RDONLY|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_REMOUNT, false, false }, /* Then, make it r/o */ #endif }; @@ -2273,7 +2278,7 @@ static int drop_capabilities(void) { static int register_machine(pid_t pid, int local_ifindex) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; if (!arg_register) @@ -2430,7 +2435,7 @@ static int register_machine(pid_t pid, int local_ifindex) { static int terminate_machine(pid_t pid) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; _cleanup_bus_message_unref_ sd_bus_message *reply = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; const char *path; int r; @@ -4259,6 +4264,7 @@ static int outer_child( int pid_socket, int kmsg_socket, int rtnl_socket, + int uid_shift_socket, FDSet *fds, int argc, char *argv[]) { @@ -4317,6 +4323,16 @@ static int outer_child( if (r < 0) return r; + if (arg_userns) { + l = send(uid_shift_socket, &arg_uid_shift, sizeof(arg_uid_shift), MSG_NOSIGNAL); + if (l < 0) + return log_error_errno(errno, "Failed to send UID shift: %m"); + if (l != sizeof(arg_uid_shift)) { + log_error("Short write while sending UID shift."); + return -EIO; + } + } + /* Turn directory into bind mount */ if (mount(directory, directory, NULL, MS_BIND|MS_REC, NULL) < 0) return log_error_errno(errno, "Failed to make bind mount: %m"); @@ -4397,6 +4413,7 @@ static int outer_child( if (pid == 0) { pid_socket = safe_close(pid_socket); + uid_shift_socket = safe_close(uid_shift_socket); /* The inner child has all namespaces that are * requested, so that we all are owned by the user if @@ -4687,7 +4704,8 @@ int main(int argc, char *argv[]) { } for (;;) { - _cleanup_close_pair_ int kmsg_socket_pair[2] = { -1, -1 }, rtnl_socket_pair[2] = { -1, -1 }, pid_socket_pair[2] = { -1, -1 }; + _cleanup_close_pair_ int kmsg_socket_pair[2] = { -1, -1 }, rtnl_socket_pair[2] = { -1, -1 }, pid_socket_pair[2] = { -1, -1 }, + uid_shift_socket_pair[2] = { -1, -1 }; ContainerStatus container_status; _cleanup_(barrier_destroy) Barrier barrier = BARRIER_NULL; static const struct sigaction sa = { @@ -4696,10 +4714,10 @@ int main(int argc, char *argv[]) { }; int ifi = 0; ssize_t l; - _cleanup_event_unref_ sd_event *event = NULL; - _cleanup_(pty_forward_freep) PTYForward *forward = NULL; - _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; - char last_char = 0; + _cleanup_event_unref_ sd_event *event = NULL; + _cleanup_(pty_forward_freep) PTYForward *forward = NULL; + _cleanup_netlink_unref_ sd_netlink *rtnl = NULL; + char last_char = 0; r = barrier_create(&barrier); if (r < 0) { @@ -4722,6 +4740,12 @@ int main(int argc, char *argv[]) { goto finish; } + if (arg_userns) + if (socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, uid_shift_socket_pair) < 0) { + r = log_error_errno(errno, "Failed to create uid shift socket pair: %m"); + goto finish; + } + /* Child can be killed before execv(), so handle SIGCHLD * in order to interrupt parent's blocking calls and * give it a chance to call wait() and terminate. */ @@ -4756,6 +4780,7 @@ int main(int argc, char *argv[]) { kmsg_socket_pair[0] = safe_close(kmsg_socket_pair[0]); rtnl_socket_pair[0] = safe_close(rtnl_socket_pair[0]); pid_socket_pair[0] = safe_close(pid_socket_pair[0]); + uid_shift_socket_pair[0] = safe_close(uid_shift_socket_pair[0]); (void) reset_all_signal_handlers(); (void) reset_signal_mask(); @@ -4771,6 +4796,7 @@ int main(int argc, char *argv[]) { pid_socket_pair[1], kmsg_socket_pair[1], rtnl_socket_pair[1], + uid_shift_socket_pair[1], fds, argc, argv); if (r < 0) @@ -4819,6 +4845,17 @@ int main(int argc, char *argv[]) { goto finish; } + l = recv(uid_shift_socket_pair[0], &arg_uid_shift, sizeof(arg_uid_shift), 0); + if (l < 0) { + r = log_error_errno(errno, "Failed to read UID shift: %m"); + goto finish; + } + if (l != sizeof(arg_uid_shift)) { + log_error("Short read while reading UID shift: %m"); + r = EIO; + goto finish; + } + r = setup_uid_map(pid); if (r < 0) goto finish; diff --git a/src/nss-myhostname/Makefile b/src/nss-myhostname/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/nss-myhostname/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/nss-mymachines/Makefile b/src/nss-mymachines/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/nss-mymachines/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c index 9476ad1694..f712033e6c 100644 --- a/src/nss-mymachines/nss-mymachines.c +++ b/src/nss-mymachines/nss-mymachines.c @@ -79,7 +79,7 @@ enum nss_status _nss_mymachines_gethostbyname4_r( struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL; _cleanup_bus_message_unref_ sd_bus_message* reply = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; _cleanup_free_ int *ifindices = NULL; _cleanup_free_ char *class = NULL; size_t l, ms, idx; @@ -228,7 +228,7 @@ enum nss_status _nss_mymachines_gethostbyname3_r( char **canonp) { _cleanup_bus_message_unref_ sd_bus_message* reply = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; _cleanup_free_ char *class = NULL; unsigned c = 0, i = 0; char *r_name, *r_aliases, *r_addr, *r_addr_list; diff --git a/src/nss-resolve/Makefile b/src/nss-resolve/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/nss-resolve/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/nss-resolve/nss-resolve.c b/src/nss-resolve/nss-resolve.c index 8f181a6c72..da22f98eba 100644 --- a/src/nss-resolve/nss-resolve.c +++ b/src/nss-resolve/nss-resolve.c @@ -122,7 +122,7 @@ enum nss_status _nss_resolve_gethostbyname4_r( _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; struct gaih_addrtuple *r_tuple, *r_tuple_first = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; const char *canonical = NULL; size_t l, ms, idx; char *r_name; @@ -305,7 +305,7 @@ enum nss_status _nss_resolve_gethostbyname3_r( _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; char *r_name, *r_aliases, *r_addr, *r_addr_list; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; size_t l, idx, ms, alen; const char *canonical; int c, r, i = 0, ifindex; @@ -513,7 +513,7 @@ enum nss_status _nss_resolve_gethostbyaddr2_r( _cleanup_bus_message_unref_ sd_bus_message *req = NULL, *reply = NULL; _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; char *r_name, *r_aliases, *r_addr, *r_addr_list; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; unsigned c = 0, i = 0; size_t ms = 0, idx; const char *n; diff --git a/src/path/Makefile b/src/path/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/path/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/python-systemd/.gitignore b/src/python-systemd/.gitignore new file mode 100644 index 0000000000..4124b7affd --- /dev/null +++ b/src/python-systemd/.gitignore @@ -0,0 +1,2 @@ +/id128-constants.h +*.py[oc] diff --git a/src/python-systemd/Makefile b/src/python-systemd/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/python-systemd/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/python-systemd/docs/.gitignore b/src/python-systemd/docs/.gitignore new file mode 100644 index 0000000000..b06a965e6a --- /dev/null +++ b/src/python-systemd/docs/.gitignore @@ -0,0 +1 @@ +!layout.html diff --git a/src/python-systemd/docs/conf.py b/src/python-systemd/docs/conf.py new file mode 100644 index 0000000000..1919170bb1 --- /dev/null +++ b/src/python-systemd/docs/conf.py @@ -0,0 +1,279 @@ +# -*- coding: utf-8 -*- +# +# python-systemd documentation build configuration file, created by +# sphinx-quickstart on Sat Feb 9 13:49:42 2013. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# Note that not all possible configuration values are present in this +# autogenerated file. +# +# All configuration values have a default; values that are commented out +# serve to show the default. + +import sys, os + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +#sys.path.insert(0, os.path.abspath('.')) + +# -- General configuration ----------------------------------------------------- + +# If your documentation needs a minimal Sphinx version, state it here. +#needs_sphinx = '1.0' + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +extensions = ['sphinx.ext.autodoc', 'sphinx.ext.doctest', 'sphinx.ext.intersphinx', 'sphinx.ext.coverage', 'sphinx.ext.viewcode'] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['.'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The encoding of source files. +#source_encoding = 'utf-8-sig' + +# The master toctree document. +master_doc = 'index' + +# General information about the project. +project = u'python-systemd' + +# The language for content autogenerated by Sphinx. Refer to documentation +# for a list of supported languages. +#language = None + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +#today_fmt = '%B %d, %Y' + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +exclude_patterns = [] + +# The reST default role (used for this markup: `text`) to use for all documents. +#default_role = None + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + +# A list of ignored prefixes for module index sorting. +#modindex_common_prefix = [] + + +# -- Options for HTML output --------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +html_theme = 'default' + +# Theme options are theme-specific and customize the look and feel of a theme +# further. For a list of options available for each theme, see the +# documentation. +#html_theme_options = {} + +# Add any paths that contain custom themes here, relative to this directory. +#html_theme_path = [] + +# The name for this set of Sphinx documents. If None, it defaults to +# "<project> v<release> documentation". +#html_title = None + +# A shorter title for the navigation bar. Default is the same as html_title. +#html_short_title = None + +# The name of an image file (relative to this directory) to place at the top +# of the sidebar. +#html_logo = None + +# The name of an image file (within the static path) to use as favicon of the +# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 +# pixels large. +#html_favicon = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ['.'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +#html_last_updated_fmt = '%b %d, %Y' + +# If true, SmartyPants will be used to convert quotes and dashes to +# typographically correct entities. +#html_use_smartypants = True + +# Custom sidebar templates, maps document names to template names. +#html_sidebars = {} + +# Additional templates that should be rendered to pages, maps page names to +# template names. +#html_additional_pages = {} + +# If false, no module index is generated. +#html_domain_indices = True + +# If false, no index is generated. +#html_use_index = True + +# If true, the index is split into individual pages for each letter. +#html_split_index = False + +# If true, links to the reST sources are added to the pages. +html_show_sourcelink = False + +# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. +#html_show_sphinx = True + +# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. +#html_show_copyright = True + +# If true, an OpenSearch description file will be output, and all pages will +# contain a <link> tag referring to it. The value of this option must be the +# base URL from which the finished HTML is served. +#html_use_opensearch = '' + +# This is the file name suffix for HTML files (e.g. ".xhtml"). +#html_file_suffix = None + +# Output file base name for HTML help builder. +htmlhelp_basename = 'python-systemddoc' + + +# -- Options for LaTeX output -------------------------------------------------- + +latex_elements = { +# The paper size ('letterpaper' or 'a4paper'). +#'papersize': 'letterpaper', + +# The font size ('10pt', '11pt' or '12pt'). +#'pointsize': '10pt', + +# Additional stuff for the LaTeX preamble. +#'preamble': '', +} + +# Grouping the document tree into LaTeX files. List of tuples +# (source start file, target name, title, author, documentclass [howto/manual]). +latex_documents = [ + ('index', 'python-systemd.tex', u'python-systemd Documentation', + None, 'manual'), +] + +# The name of an image file (relative to this directory) to place at the top of +# the title page. +#latex_logo = None + +# For "manual" documents, if this is true, then toplevel headings are parts, +# not chapters. +#latex_use_parts = False + +# If true, show page references after internal links. +#latex_show_pagerefs = False + +# If true, show URL addresses after external links. +#latex_show_urls = False + +# Documents to append as an appendix to all manuals. +#latex_appendices = [] + +# If false, no module index is generated. +#latex_domain_indices = True + + +# -- Options for manual page output -------------------------------------------- + +# One entry per manual page. List of tuples +# (source start file, name, description, authors, manual section). +man_pages = [ + ('index', 'python-systemd', u'python-systemd Documentation', + [], 1) +] + +# If true, show URL addresses after external links. +#man_show_urls = False + + +# -- Options for Texinfo output ------------------------------------------------ + +# Grouping the document tree into Texinfo files. List of tuples +# (source start file, target name, title, author, +# dir menu entry, description, category) +texinfo_documents = [ + ('index', 'python-systemd', u'python-systemd Documentation', + u'David Strauss, Zbigniew Jędrzejewski-Szmek, Marti Raudsepp, Steven Hiscocks', 'python-systemd', 'One line description of project.', + 'Miscellaneous'), +] + +# Documents to append as an appendix to all manuals. +#texinfo_appendices = [] + +# If false, no module index is generated. +#texinfo_domain_indices = True + +# How to display URL addresses: 'footnote', 'no', or 'inline'. +#texinfo_show_urls = 'footnote' + + +# -- Options for Epub output --------------------------------------------------- + +# Bibliographic Dublin Core info. +epub_title = u'python-systemd' +epub_author = u'David Strauss, Zbigniew Jędrzejewski-Szmek, Marti Raudsepp, Steven Hiscocks' +epub_publisher = u'David Strauss, Zbigniew Jędrzejewski-Szmek, Marti Raudsepp, Steven Hiscocks' +epub_copyright = u'2013, David Strauss, Zbigniew Jędrzejewski-Szmek, Marti Raudsepp, Steven Hiscocks' + +# The language of the text. It defaults to the language option +# or en if the language is not set. +#epub_language = '' + +# The scheme of the identifier. Typical schemes are ISBN or URL. +#epub_scheme = '' + +# The unique identifier of the text. This can be a ISBN number +# or the project homepage. +#epub_identifier = '' + +# A unique identification for the text. +#epub_uid = '' + +# A tuple containing the cover image and cover page html template filenames. +#epub_cover = () + +# HTML files that should be inserted before the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_pre_files = [] + +# HTML files shat should be inserted after the pages created by sphinx. +# The format is a list of tuples containing the path and title. +#epub_post_files = [] + +# A list of files that should not be packed into the epub file. +#epub_exclude_files = [] + +# The depth of the table of contents in toc.ncx. +#epub_tocdepth = 3 + +# Allow duplicate toc entries. +#epub_tocdup = True + + +# Example configuration for intersphinx: refer to the Python standard library. +intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/src/python-systemd/docs/daemon.rst b/src/python-systemd/docs/daemon.rst new file mode 100644 index 0000000000..0ad11edaf3 --- /dev/null +++ b/src/python-systemd/docs/daemon.rst @@ -0,0 +1,18 @@ +`systemd.daemon` module +======================= + +.. automodule:: systemd.daemon + :members: + :undoc-members: + :inherited-members: + + .. autoattribute:: systemd.daemon.LISTEN_FDS_START + + .. autofunction:: _listen_fds + .. autofunction:: _is_fifo + .. autofunction:: _is_socket + .. autofunction:: _is_socket_unix + .. autofunction:: _is_socket_inet + .. autofunction:: _is_mq + .. autofunction:: notify + .. autofunction:: booted diff --git a/src/python-systemd/docs/default.css b/src/python-systemd/docs/default.css new file mode 100644 index 0000000000..7c097d64a2 --- /dev/null +++ b/src/python-systemd/docs/default.css @@ -0,0 +1,196 @@ +@import url("basic.css"); + +/* -- page layout ----------------------------------------------------------- */ + +div.documentwrapper { + float: left; + width: 100%; +} + +div.bodywrapper { + margin: 0 0 0 230px; +} + +div.body { + background-color: #ffffff; + color: #000000; + padding: 0 20px 30px 20px; +} + +div.footer { + color: #ffffff; + width: 100%; + padding: 9px 0 9px 0; + text-align: center; + font-size: 75%; +} + +div.footer a { + color: #ffffff; + text-decoration: underline; +} + +div.related { + background-color: #133f52; + line-height: 30px; + color: #ffffff; +} + +div.related a { + color: #ffffff; +} + +div.sphinxsidebar { + background-color: #dddddd; +} + +div.sphinxsidebar p.topless { + margin: 5px 10px 10px 10px; +} + +div.sphinxsidebar ul { + margin: 10px; + padding: 0; +} + +div.sphinxsidebar input { + border: 1px solid #000000; + font-family: sans-serif; + font-size: 1em; +} + + + +/* -- hyperlink styles ------------------------------------------------------ */ + +a { + text-decoration: none; +} + +a:hover { + text-decoration: underline; +} + + + +/* -- body styles ----------------------------------------------------------- */ + +div.body h1, +div.body h2, +div.body h3, +div.body h4, +div.body h5, +div.body h6 { + font-family: 'Trebuchet MS', sans-serif; + background-color: #f2f2f2; + font-weight: normal; + color: #20435c; + border-bottom: 1px solid #ccc; + margin: 20px -20px 10px -20px; + padding: 3px 0 3px 10px; +} + +div.body h1 { margin-top: 0; font-size: 200%; } +div.body h2 { font-size: 160%; } +div.body h3 { font-size: 140%; } +div.body h4 { font-size: 120%; } +div.body h5 { font-size: 110%; } +div.body h6 { font-size: 100%; } + +a.headerlink { + color: #c60f0f; + font-size: 0.8em; + padding: 0 4px 0 4px; + text-decoration: none; +} + +a.headerlink:hover { + background-color: #c60f0f; + color: white; +} + +div.body p, div.body dd, div.body li { + text-align: justify; + line-height: 130%; +} + +div.admonition p.admonition-title + p { + display: inline; +} + +div.admonition p { + margin-bottom: 5px; +} + +div.admonition pre { + margin-bottom: 5px; +} + +div.admonition ul, div.admonition ol { + margin-bottom: 5px; +} + +div.note { + background-color: #eee; + border: 1px solid #ccc; +} + +div.seealso { + background-color: #ffc; + border: 1px solid #ff6; +} + +div.topic { + background-color: #eee; +} + +div.warning { + background-color: #ffe4e4; + border: 1px solid #f66; +} + +p.admonition-title { + display: inline; +} + +p.admonition-title:after { + content: ":"; +} + +pre { + padding: 5px; + background-color: #eeffcc; + color: #333333; + line-height: 120%; + border: 1px solid #ac9; + border-left: none; + border-right: none; +} + +tt { + background-color: #ecf0f3; + padding: 0 1px 0 1px; + font-size: 0.95em; +} + +th { + background-color: #ede; +} + +.warning tt { + background: #efc2c2; +} + +.note tt { + background: #d6d6d6; +} + +.viewcode-back { + font-family: sans-serif; +} + +div.viewcode-block:target { + background-color: #f4debf; + border-top: 1px solid #ac9; + border-bottom: 1px solid #ac9; +} diff --git a/src/python-systemd/docs/id128.rst b/src/python-systemd/docs/id128.rst new file mode 100644 index 0000000000..89c37f3470 --- /dev/null +++ b/src/python-systemd/docs/id128.rst @@ -0,0 +1,40 @@ +`systemd.id128` module +====================== + +.. automodule:: systemd.id128 + :members: + :undoc-members: + :inherited-members: + + .. autoattribute:: systemd.id128.SD_MESSAGE_COREDUMP + .. autoattribute:: systemd.id128.SD_MESSAGE_FORWARD_SYSLOG_MISSED + .. autoattribute:: systemd.id128.SD_MESSAGE_HIBERNATE_KEY + .. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_DROPPED + .. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_MISSED + .. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_START + .. autoattribute:: systemd.id128.SD_MESSAGE_JOURNAL_STOP + .. autoattribute:: systemd.id128.SD_MESSAGE_LID_CLOSED + .. autoattribute:: systemd.id128.SD_MESSAGE_LID_OPENED + .. autoattribute:: systemd.id128.SD_MESSAGE_OVERMOUNTING + .. autoattribute:: systemd.id128.SD_MESSAGE_POWER_KEY + .. autoattribute:: systemd.id128.SD_MESSAGE_SEAT_START + .. autoattribute:: systemd.id128.SD_MESSAGE_SEAT_STOP + .. autoattribute:: systemd.id128.SD_MESSAGE_SESSION_START + .. autoattribute:: systemd.id128.SD_MESSAGE_SESSION_STOP + .. autoattribute:: systemd.id128.SD_MESSAGE_SHUTDOWN + .. autoattribute:: systemd.id128.SD_MESSAGE_SLEEP_START + .. autoattribute:: systemd.id128.SD_MESSAGE_SLEEP_STOP + .. autoattribute:: systemd.id128.SD_MESSAGE_SPAWN_FAILED + .. autoattribute:: systemd.id128.SD_MESSAGE_STARTUP_FINISHED + .. autoattribute:: systemd.id128.SD_MESSAGE_SUSPEND_KEY + .. autoattribute:: systemd.id128.SD_MESSAGE_TIMEZONE_CHANGE + .. autoattribute:: systemd.id128.SD_MESSAGE_TIME_CHANGE + .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_FAILED + .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_RELOADED + .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_RELOADING + .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STARTED + .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STARTING + .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPED + .. autoattribute:: systemd.id128.SD_MESSAGE_UNIT_STOPPING + .. autoattribute:: systemd.id128.SD_MESSAGE_CONFIG_ERROR + .. autoattribute:: systemd.id128.SD_MESSAGE_BOOTCHART diff --git a/src/python-systemd/docs/index.rst b/src/python-systemd/docs/index.rst new file mode 100644 index 0000000000..e78d966274 --- /dev/null +++ b/src/python-systemd/docs/index.rst @@ -0,0 +1,24 @@ +.. python-systemd documentation master file, created by + sphinx-quickstart on Sat Feb 9 13:49:42 2013. + You can adapt this file completely to your liking, but it should at least + contain the root `toctree` directive. + +Welcome to python-systemd's documentation! +========================================== + +Contents: + +.. toctree:: + :maxdepth: 2 + + journal + id128 + daemon + login + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/src/python-systemd/docs/journal.rst b/src/python-systemd/docs/journal.rst new file mode 100644 index 0000000000..ea74cf85c4 --- /dev/null +++ b/src/python-systemd/docs/journal.rst @@ -0,0 +1,64 @@ +`systemd.journal` module +======================== + +.. automodule:: systemd.journal + :members: send, sendv, stream, stream_fd + :undoc-members: + +`JournalHandler` class +---------------------- + +.. autoclass:: JournalHandler + +Accessing the Journal +--------------------- + +.. autoclass:: _Reader + :undoc-members: + :inherited-members: + +.. autoclass:: Reader + :undoc-members: + :inherited-members: + + .. automethod:: __init__ + +.. autofunction:: _get_catalog +.. autofunction:: get_catalog + +.. autoclass:: Monotonic + +.. autoattribute:: systemd.journal.DEFAULT_CONVERTERS + +Example: polling for journal events +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example shows that journal events can be waited for (using +e.g. `poll`). This makes it easy to integrate Reader in an external +event loop: + + >>> import select + >>> from systemd import journal + >>> j = journal.Reader() + >>> j.seek_tail() + >>> p = select.poll() + >>> p.register(j, j.get_events()) + >>> p.poll() + [(3, 1)] + >>> j.get_next() + + +Journal access types +~~~~~~~~~~~~~~~~~~~~ + +.. autoattribute:: systemd.journal.LOCAL_ONLY +.. autoattribute:: systemd.journal.RUNTIME_ONLY +.. autoattribute:: systemd.journal.SYSTEM +.. autoattribute:: systemd.journal.CURRENT_USER + +Journal event types +~~~~~~~~~~~~~~~~~~~ + +.. autoattribute:: systemd.journal.NOP +.. autoattribute:: systemd.journal.APPEND +.. autoattribute:: systemd.journal.INVALIDATE diff --git a/src/python-systemd/docs/layout.html b/src/python-systemd/docs/layout.html new file mode 100644 index 0000000000..930a6a7afe --- /dev/null +++ b/src/python-systemd/docs/layout.html @@ -0,0 +1,15 @@ +{% extends "!layout.html" %} + +{% block relbar1 %} + <a href="../man/systemd.index.html">Index </a>· + <a href="../man/systemd.directives.html">Directives </a>· + <a href="index.html">Python </a>· + <span style="float:right">systemd {{release}}</span> + <hr /> +{% endblock %} + +{# remove the lower relbar #} +{% block relbar2 %} {% endblock %} + +{# remove the footer #} +{% block footer %} {% endblock %} diff --git a/src/python-systemd/docs/login.rst b/src/python-systemd/docs/login.rst new file mode 100644 index 0000000000..6b4de64c55 --- /dev/null +++ b/src/python-systemd/docs/login.rst @@ -0,0 +1,28 @@ +`systemd.login` module +======================= + +.. automodule:: systemd.login + :members: + +.. autoclass:: Monitor + :undoc-members: + :inherited-members: + +Example: polling for events +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This example shows that session/uid/seat/machine events can be waited +for (using e.g. `poll`). This makes it easy to integrate Monitor in an +external event loop: + + >>> import select + >>> from systemd import login + >>> m = login.Monitor("machine") + >>> p = select.poll() + >>> p.register(m, m.get_events()) + >>> login.machine_names() + [] + >>> p.poll() + [(3, 1)] + >>> login.machine_names() + ['fedora-19.nspawn'] diff --git a/src/quotacheck/Makefile b/src/quotacheck/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/quotacheck/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/random-seed/Makefile b/src/random-seed/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/random-seed/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/rc-local-generator/Makefile b/src/rc-local-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/rc-local-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/remount-fs/Makefile b/src/remount-fs/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/remount-fs/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/reply-password/Makefile b/src/reply-password/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/reply-password/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/resolve-host/Makefile b/src/resolve-host/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/resolve-host/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/resolve-host/resolve-host.c b/src/resolve-host/resolve-host.c index 068756cab1..f9448e3bc5 100644 --- a/src/resolve-host/resolve-host.c +++ b/src/resolve-host/resolve-host.c @@ -592,7 +592,7 @@ static int parse_argv(int argc, char *argv[]) { } int main(int argc, char **argv) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; log_parse_environment(); diff --git a/src/resolve/.gitignore b/src/resolve/.gitignore new file mode 100644 index 0000000000..f0835923b7 --- /dev/null +++ b/src/resolve/.gitignore @@ -0,0 +1,6 @@ +/resolved-gperf.c +/resolved.conf +/dns_type-from-name.gperf +/dns_type-from-name.h +/dns_type-list.txt +/dns_type-to-name.h diff --git a/src/resolve/Makefile b/src/resolve/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/resolve/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/rfkill/Makefile b/src/rfkill/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/rfkill/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/run/Makefile b/src/run/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/run/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/run/run.c b/src/run/run.c index 99d960a664..148854a9b5 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -1099,7 +1099,7 @@ static int start_transient_timer( } int main(int argc, char* argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; _cleanup_free_ char *description = NULL, *command = NULL; int r; diff --git a/src/shared/bus-util.h b/src/shared/bus-util.h index d8dba584d6..4ae216b7d9 100644 --- a/src/shared/bus-util.h +++ b/src/shared/bus-util.h @@ -135,22 +135,15 @@ typedef struct UnitInfo { int bus_parse_unit_info(sd_bus_message *message, UnitInfo *u); -static inline void sd_bus_close_unrefp(sd_bus **bus) { - if (*bus) { - sd_bus_flush(*bus); - sd_bus_close(*bus); - sd_bus_unref(*bus); - } -} - DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_unref); +DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus*, sd_bus_flush_close_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_slot*, sd_bus_slot_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_message*, sd_bus_message_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_creds*, sd_bus_creds_unref); DEFINE_TRIVIAL_CLEANUP_FUNC(sd_bus_track*, sd_bus_track_unref); #define _cleanup_bus_unref_ _cleanup_(sd_bus_unrefp) -#define _cleanup_bus_close_unref_ _cleanup_(sd_bus_close_unrefp) +#define _cleanup_bus_flush_close_unref_ _cleanup_(sd_bus_flush_close_unrefp) #define _cleanup_bus_slot_unref_ _cleanup_(sd_bus_slot_unrefp) #define _cleanup_bus_message_unref_ _cleanup_(sd_bus_message_unrefp) #define _cleanup_bus_creds_unref_ _cleanup_(sd_bus_creds_unrefp) diff --git a/src/shared/install.c b/src/shared/install.c index 6172c42d69..c37cf1948a 100644 --- a/src/shared/install.c +++ b/src/shared/install.c @@ -220,7 +220,7 @@ static int remove_marked_symlinks_fd( instance_whitelist && !strv_contains(instance_whitelist, de->d_name)) { - _cleanup_free_ char *w; + _cleanup_free_ char *w = NULL; /* OK, the file is not listed directly * in the whitelist, so let's check if @@ -2263,7 +2263,7 @@ int unit_file_get_list( } } - return r; + return 0; } static const char* const unit_file_state_table[_UNIT_FILE_STATE_MAX] = { diff --git a/src/sleep/Makefile b/src/sleep/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/sleep/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/socket-proxy/Makefile b/src/socket-proxy/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/socket-proxy/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/sysctl/Makefile b/src/sysctl/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/sysctl/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/system-update-generator/Makefile b/src/system-update-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/system-update-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/systemctl/Makefile b/src/systemctl/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/systemctl/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 538838b7fc..6db4d6587a 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -617,7 +617,7 @@ static int get_unit_list_recursive( return r; STRV_FOREACH(i, machines) { - _cleanup_bus_close_unref_ sd_bus *container = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *container = NULL; int k; r = sd_bus_open_system_machine(&container, *i); @@ -1709,7 +1709,7 @@ static int compare_machine_info(const void *a, const void *b) { } static int get_machine_properties(sd_bus *bus, struct machine_info *mi) { - _cleanup_bus_close_unref_ sd_bus *container = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *container = NULL; int r; assert(mi); @@ -7340,7 +7340,7 @@ static int halt_main(sd_bus *bus) { if (arg_when > 0) { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_close_unref_ sd_bus *b = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; _cleanup_free_ char *m = NULL; if (avoid_bus()) { @@ -7449,7 +7449,7 @@ static int runlevel_main(void) { } int main(int argc, char*argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); @@ -7517,7 +7517,7 @@ int main(int argc, char*argv[]) { case ACTION_CANCEL_SHUTDOWN: { _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL; - _cleanup_bus_close_unref_ sd_bus *b = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *b = NULL; _cleanup_free_ char *m = NULL; if (avoid_bus()) { diff --git a/src/systemd/Makefile b/src/systemd/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/systemd/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h index 57e46ced8e..f34893171f 100644 --- a/src/systemd/sd-bus.h +++ b/src/systemd/sd-bus.h @@ -156,6 +156,7 @@ void sd_bus_close(sd_bus *bus); sd_bus *sd_bus_ref(sd_bus *bus); sd_bus *sd_bus_unref(sd_bus *bus); +sd_bus *sd_bus_flush_close_unref(sd_bus *bus); int sd_bus_is_open(sd_bus *bus); diff --git a/src/sysusers/Makefile b/src/sysusers/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/sysusers/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/sysv-generator/Makefile b/src/sysv-generator/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/sysv-generator/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c index 9ae518ac4a..45b119362c 100644 --- a/src/sysv-generator/sysv-generator.c +++ b/src/sysv-generator/sysv-generator.c @@ -240,20 +240,21 @@ static bool usage_contains_reload(const char *line) { } static char *sysv_translate_name(const char *name) { - char *r; + _cleanup_free_ char *c = NULL; + char *res; - r = new(char, strlen(name) + strlen(".service") + 1); - if (!r) + c = strdup(name); + if (!c) return NULL; - if (endswith(name, ".sh")) - /* Drop .sh suffix */ - strcpy(stpcpy(r, name) - 3, ".service"); - else - /* Normal init script name */ - strcpy(stpcpy(r, name), ".service"); + res = endswith(c, ".sh"); + if (res) + *res = 0; - return r; + if (unit_name_mangle(c, UNIT_NAME_NOGLOB, &res) < 0) + return NULL; + + return res; } static int sysv_translate_facility(const char *name, const char *filename, char **_r) { @@ -340,6 +341,7 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co FOREACH_WORD_QUOTED(word, z, text, state_) { _cleanup_free_ char *n = NULL, *m = NULL; + UnitType t; n = strndup(word, z); if (!n) @@ -351,12 +353,13 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co if (r == 0) continue; - if (unit_name_to_type(m) == UNIT_SERVICE) { + t = unit_name_to_type(m); + if (t == UNIT_SERVICE) { log_debug("Adding Provides: alias '%s' for '%s'", m, s->name); r = add_alias(s->name, m); if (r < 0) log_warning_errno(r, "[%s:%u] Failed to add LSB Provides name %s, ignoring: %m", s->path, line, m); - } else { + } else if (t == UNIT_TARGET) { /* NB: SysV targets which are provided by a * service are pulled in by the services, as * an indication that the generic service is @@ -373,7 +376,10 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co if (r < 0) return log_oom(); } - } + } else if (t == _UNIT_TYPE_INVALID) + log_warning("Unit name '%s' is invalid", m); + else + log_warning("Unknown unit type for unit '%s'", m); } if (!isempty(state_)) log_error("[%s:%u] Trailing garbage in Provides, ignoring.", s->path, line); diff --git a/src/test/.gitignore b/src/test/.gitignore new file mode 100644 index 0000000000..e4c198a4f7 --- /dev/null +++ b/src/test/.gitignore @@ -0,0 +1 @@ +test-hashmap-ordered.c diff --git a/src/test/Makefile b/src/test/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/test/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/test/test-copy.c b/src/test/test-copy.c index e55ffaa16a..b1385b8b87 100644 --- a/src/test/test-copy.c +++ b/src/test/test-copy.c @@ -139,7 +139,9 @@ static void test_copy_bytes(void) { int r, r2; char buf[1024], buf2[1024]; - infd = open("/etc/os-release", O_RDONLY|O_CLOEXEC); + infd = open("/usr/lib/os-release", O_RDONLY|O_CLOEXEC); + if (infd < 0) + infd = open("/etc/os-release", O_RDONLY|O_CLOEXEC); assert_se(infd >= 0); assert_se(pipe2(pipefd, O_CLOEXEC) == 0); diff --git a/src/test/test-pty.c b/src/test/test-pty.c index 3f97a64ccd..fbab3d4ebe 100644 --- a/src/test/test-pty.c +++ b/src/test/test-pty.c @@ -133,7 +133,7 @@ int main(int argc, char *argv[]) { /* Oh, there're ugly races in the TTY layer regarding HUP vs IN. Turns * out they appear only 10% of the time. I fixed all of them and - * don't see them, anymore. But lets be safe and run this 1000 times + * don't see them, anymore. But let's be safe and run this 1000 times * so we catch any new ones, in case they appear again. */ for (i = 0; i < 1000; ++i) test_pty(); diff --git a/src/timedate/.gitignore b/src/timedate/.gitignore new file mode 100644 index 0000000000..48757f0968 --- /dev/null +++ b/src/timedate/.gitignore @@ -0,0 +1 @@ +org.freedesktop.timedate1.policy diff --git a/src/timedate/Makefile b/src/timedate/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/timedate/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/timedate/timedatectl.c b/src/timedate/timedatectl.c index 195d5f3892..240578bca0 100644 --- a/src/timedate/timedatectl.c +++ b/src/timedate/timedatectl.c @@ -154,11 +154,12 @@ static void print_status_info(const StatusInfo *i) { if (i->rtc_local) fputs("\n" ANSI_HIGHLIGHT_ON - "Warning: The system is configured to read the RTC time in the local time zone. This\n" - " mode can not be fully supported. It will create various problems with time\n" - " zone changes and daylight saving time adjustments. The RTC time is never updated,\n" - " it relies on external facilities to maintain it. If at all possible, use\n" - " RTC in UTC by calling 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout); + "Warning: The system is configured to read the RTC time in the local time zone.\n" + " This mode can not be fully supported. It will create various problems\n" + " with time zone changes and daylight saving time adjustments. The RTC\n" + " time is never updated, it relies on external facilities to maintain it.\n" + " If at all possible, use RTC in UTC by calling\n" + " 'timedatectl set-local-rtc 0'" ANSI_HIGHLIGHT_OFF ".\n", stdout); } static int show_status(sd_bus *bus, char **args, unsigned n) { @@ -490,7 +491,7 @@ static int timedatectl_main(sd_bus *bus, int argc, char *argv[]) { } int main(int argc, char *argv[]) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; setlocale(LC_ALL, ""); diff --git a/src/timedate/timedated.c b/src/timedate/timedated.c index 4e8ae94717..21d6ee4c0c 100644 --- a/src/timedate/timedated.c +++ b/src/timedate/timedated.c @@ -660,7 +660,7 @@ static const sd_bus_vtable timedate_vtable[] = { }; static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; assert(c); @@ -692,7 +692,7 @@ static int connect_bus(Context *c, sd_event *event, sd_bus **_bus) { int main(int argc, char *argv[]) { Context context = {}; _cleanup_event_unref_ sd_event *event = NULL; - _cleanup_bus_close_unref_ sd_bus *bus = NULL; + _cleanup_bus_flush_close_unref_ sd_bus *bus = NULL; int r; log_set_target(LOG_TARGET_AUTO); diff --git a/src/timesync/.gitignore b/src/timesync/.gitignore new file mode 100644 index 0000000000..35f4d76f79 --- /dev/null +++ b/src/timesync/.gitignore @@ -0,0 +1,2 @@ +/timesyncd.conf +/timesyncd-gperf.c diff --git a/src/timesync/Makefile b/src/timesync/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/timesync/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/tmpfiles/Makefile b/src/tmpfiles/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/tmpfiles/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/tty-ask-password-agent/Makefile b/src/tty-ask-password-agent/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/tty-ask-password-agent/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/udev/.gitignore b/src/udev/.gitignore new file mode 100644 index 0000000000..ba112ce218 --- /dev/null +++ b/src/udev/.gitignore @@ -0,0 +1,5 @@ +/udev.pc +/keyboard-keys-from-name.gperf +/keyboard-keys-from-name.h +/keyboard-keys-to-name.h +/keyboard-keys-list.txt diff --git a/src/udev/.vimrc b/src/udev/.vimrc new file mode 100644 index 0000000000..366fbdca4b --- /dev/null +++ b/src/udev/.vimrc @@ -0,0 +1,4 @@ +" 'set exrc' in ~/.vimrc will read .vimrc from the current directory +set tabstop=8 +set shiftwidth=8 +set expandtab diff --git a/src/udev/Makefile b/src/udev/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/udev/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/udev/accelerometer/accelerometer.c b/src/udev/accelerometer/accelerometer.c deleted file mode 100644 index 9e2c590c15..0000000000 --- a/src/udev/accelerometer/accelerometer.c +++ /dev/null @@ -1,303 +0,0 @@ -/* - * accelerometer - exports device orientation through property - * - * When an "change" event is received on an accelerometer, - * open its device node, and from the value, as well as the previous - * value of the property, calculate the device's new orientation, - * and export it as ID_INPUT_ACCELEROMETER_ORIENTATION. - * - * Possible values are: - * undefined - * * normal - * * bottom-up - * * left-up - * * right-up - * - * The property will be persistent across sessions, and the new - * orientations can be deducted from the previous one (it allows - * for a threshold for switching between opposite ends of the - * orientation). - * - * Copyright (C) 2011 Red Hat, Inc. - * Author: - * Bastien Nocera <hadess@hadess.net> - * - * orientation_calc() from the sensorfw package - * Copyright (C) 2009-2010 Nokia Corporation - * Authors: - * Üstün Ergenoglu <ext-ustun.ergenoglu@nokia.com> - * Timo Rongas <ext-timo.2.rongas@nokia.com> - * Lihan Guo <lihan.guo@digia.com> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License along - * with this program; if not, write to the Free Software Foundation, Inc., - * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - */ - -#include <stdio.h> -#include <string.h> -#include <math.h> -#include <stdlib.h> -#include <getopt.h> -#include <limits.h> -#include <linux/input.h> - -#include "libudev.h" -#include "libudev-private.h" - -/* we must use this kernel-compatible implementation */ -#define BITS_PER_LONG (sizeof(unsigned long) * 8) -#define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) -#define OFF(x) ((x)%BITS_PER_LONG) -#define BIT(x) (1UL<<OFF(x)) -#define LONG(x) ((x)/BITS_PER_LONG) -#define test_bit(bit, array) ((array[LONG(bit)] >> OFF(bit)) & 1) - -typedef enum { - ORIENTATION_UNDEFINED, - ORIENTATION_NORMAL, - ORIENTATION_BOTTOM_UP, - ORIENTATION_LEFT_UP, - ORIENTATION_RIGHT_UP -} OrientationUp; - -static const char *orientations[] = { - "undefined", - "normal", - "bottom-up", - "left-up", - "right-up", - NULL -}; - -#define ORIENTATION_UP_UP ORIENTATION_NORMAL - -#define DEFAULT_THRESHOLD 250 -#define RADIANS_TO_DEGREES 180.0/M_PI -#define SAME_AXIS_LIMIT 5 - -#define THRESHOLD_LANDSCAPE 25 -#define THRESHOLD_PORTRAIT 20 - -static const char * -orientation_to_string (OrientationUp o) -{ - return orientations[o]; -} - -static OrientationUp -string_to_orientation (const char *orientation) -{ - int i; - - if (orientation == NULL) - return ORIENTATION_UNDEFINED; - for (i = 0; orientations[i] != NULL; i++) { - if (streq (orientation, orientations[i])) - return i; - } - return ORIENTATION_UNDEFINED; -} - -static OrientationUp -orientation_calc (OrientationUp prev, - int x, int y, int z) -{ - int rotation; - OrientationUp ret = prev; - - /* Portrait check */ - rotation = round(atan((double) x / sqrt(y * y + z * z)) * RADIANS_TO_DEGREES); - - if (abs(rotation) > THRESHOLD_PORTRAIT) { - ret = (rotation < 0) ? ORIENTATION_LEFT_UP : ORIENTATION_RIGHT_UP; - - /* Some threshold to switching between portrait modes */ - if (prev == ORIENTATION_LEFT_UP || prev == ORIENTATION_RIGHT_UP) { - if (abs(rotation) < SAME_AXIS_LIMIT) { - ret = prev; - } - } - - } else { - /* Landscape check */ - rotation = round(atan((double) y / sqrt(x * x + z * z)) * RADIANS_TO_DEGREES); - - if (abs(rotation) > THRESHOLD_LANDSCAPE) { - ret = (rotation < 0) ? ORIENTATION_BOTTOM_UP : ORIENTATION_NORMAL; - - /* Some threshold to switching between landscape modes */ - if (prev == ORIENTATION_BOTTOM_UP || prev == ORIENTATION_NORMAL) { - if (abs(rotation) < SAME_AXIS_LIMIT) { - ret = prev; - } - } - } - } - - return ret; -} - -static OrientationUp -get_prev_orientation(struct udev_device *dev) -{ - const char *value; - - value = udev_device_get_property_value(dev, "ID_INPUT_ACCELEROMETER_ORIENTATION"); - if (value == NULL) - return ORIENTATION_UNDEFINED; - return string_to_orientation(value); -} - -#define READ_AXIS(axis, var) { memzero(&abs_info, sizeof(abs_info)); r = ioctl(fd, EVIOCGABS(axis), &abs_info); if (r < 0) return; var = abs_info.value; } - -/* accelerometers */ -static void test_orientation(struct udev *udev, - struct udev_device *dev, - const char *devpath) -{ - OrientationUp old, new; - _cleanup_close_ int fd = -1; - struct input_absinfo abs_info; - int x = 0, y = 0, z = 0; - int r; - char text[64]; - - old = get_prev_orientation(dev); - - fd = open(devpath, O_RDONLY|O_CLOEXEC); - if (fd < 0) - return; - - READ_AXIS(ABS_X, x); - READ_AXIS(ABS_Y, y); - READ_AXIS(ABS_Z, z); - - new = orientation_calc(old, x, y, z); - snprintf(text, sizeof(text), - "ID_INPUT_ACCELEROMETER_ORIENTATION=%s", orientation_to_string(new)); - puts(text); -} - -static void help(void) { - - printf("%s [options] <device path>\n\n" - "Accelerometer device identification.\n\n" - " -h --help Print this message\n" - " -d --debug Debug to stderr\n" - , program_invocation_short_name); -} - -int main (int argc, char** argv) -{ - struct udev *udev; - struct udev_device *dev; - - static const struct option options[] = { - { "debug", no_argument, NULL, 'd' }, - { "help", no_argument, NULL, 'h' }, - {} - }; - - char devpath[PATH_MAX]; - char *devnode; - struct udev_enumerate *enumerate; - struct udev_list_entry *list_entry; - - log_parse_environment(); - log_open(); - - udev = udev_new(); - if (udev == NULL) - return 1; - - /* CLI argument parsing */ - while (1) { - int option; - - option = getopt_long(argc, argv, "dh", options, NULL); - if (option == -1) - break; - - switch (option) { - case 'd': - log_set_target(LOG_TARGET_CONSOLE); - log_set_max_level(LOG_DEBUG); - log_open(); - break; - case 'h': - help(); - exit(0); - default: - exit(1); - } - } - - if (argv[optind] == NULL) { - help(); - exit(1); - } - - /* get the device */ - snprintf(devpath, sizeof(devpath), "/sys/%s", argv[optind]); - dev = udev_device_new_from_syspath(udev, devpath); - if (dev == NULL) { - fprintf(stderr, "unable to access '%s'\n", devpath); - return 1; - } - - /* Get the children devices and find the devnode */ - devnode = NULL; - enumerate = udev_enumerate_new(udev); - udev_enumerate_add_match_parent(enumerate, dev); - udev_enumerate_scan_devices(enumerate); - udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(enumerate)) { - struct udev_device *device; - const char *node; - - device = udev_device_new_from_syspath(udev_enumerate_get_udev(enumerate), - udev_list_entry_get_name(list_entry)); - if (device == NULL) - continue; - /* Already found it */ - if (devnode != NULL) { - udev_device_unref(device); - continue; - } - - node = udev_device_get_devnode(device); - if (node == NULL) { - udev_device_unref(device); - continue; - } - /* Use the event sub-device */ - if (strstr(node, "/event") == NULL) { - udev_device_unref(device); - continue; - } - - devnode = strdup(node); - udev_device_unref(device); - } - - if (devnode == NULL) { - fprintf(stderr, "unable to get device node for '%s'\n", devpath); - return 0; - } - - log_debug("opening accelerometer device %s", devnode); - test_orientation(udev, dev, devnode); - free(devnode); - log_close(); - return 0; -} diff --git a/src/udev/ata_id/Makefile b/src/udev/ata_id/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/udev/ata_id/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/udev/ata_id/ata_id.c b/src/udev/ata_id/ata_id.c index cc1bf45ae9..7ba0b7fc8f 100644 --- a/src/udev/ata_id/ata_id.c +++ b/src/udev/ata_id/ata_id.c @@ -639,8 +639,8 @@ int main(int argc, char *argv[]) */ word = identify.wyde[108]; if ((word & 0xf000) == 0x5000) - printf("ID_WWN=0x%1$"PRIu64"x\n" - "ID_WWN_WITH_EXTENSION=0x%1$"PRIu64"x\n", + printf("ID_WWN=0x%1$" PRIx64 "\n" + "ID_WWN_WITH_EXTENSION=0x%1$" PRIx64 "\n", identify.octa[108/4]); /* from Linux's include/linux/ata.h */ diff --git a/src/udev/cdrom_id/Makefile b/src/udev/cdrom_id/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/udev/cdrom_id/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/udev/collect/Makefile b/src/udev/collect/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/udev/collect/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/udev/mtd_probe/Makefile b/src/udev/mtd_probe/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/udev/mtd_probe/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/udev/net/.gitignore b/src/udev/net/.gitignore new file mode 100644 index 0000000000..9ca85bacc9 --- /dev/null +++ b/src/udev/net/.gitignore @@ -0,0 +1 @@ +/link-config-gperf.c diff --git a/src/udev/net/Makefile b/src/udev/net/Makefile new file mode 120000 index 0000000000..94aaae2c4d --- /dev/null +++ b/src/udev/net/Makefile @@ -0,0 +1 @@ +../../Makefile
\ No newline at end of file diff --git a/src/udev/scsi_id/.gitignore b/src/udev/scsi_id/.gitignore new file mode 100644 index 0000000000..6aebddd809 --- /dev/null +++ b/src/udev/scsi_id/.gitignore @@ -0,0 +1 @@ +scsi_id_version.h diff --git a/src/udev/scsi_id/Makefile b/src/udev/scsi_id/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/udev/scsi_id/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/udev/udev-builtin-hwdb.c b/src/udev/udev-builtin-hwdb.c index 7dfc74e6fa..b656204c46 100644 --- a/src/udev/udev-builtin-hwdb.c +++ b/src/udev/udev-builtin-hwdb.c @@ -26,6 +26,7 @@ #include "sd-hwdb.h" #include "hwdb-util.h" +#include "udev-util.h" static sd_hwdb *hwdb; @@ -87,6 +88,9 @@ static int udev_builtin_hwdb_search(struct udev_device *dev, struct udev_device assert(dev); + if (!srcdev) + srcdev = dev; + for (d = srcdev; d && !last; d = udev_device_get_parent(d)) { const char *dsubsys; const char *modalias = NULL; @@ -133,7 +137,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te const char *device = NULL; const char *subsystem = NULL; const char *prefix = NULL; - struct udev_device *srcdev; + _cleanup_udev_device_unref_ struct udev_device *srcdev = NULL; if (!hwdb) return EXIT_FAILURE; @@ -176,8 +180,7 @@ static int builtin_hwdb(struct udev_device *dev, int argc, char *argv[], bool te srcdev = udev_device_new_from_device_id(udev_device_get_udev(dev), device); if (!srcdev) return EXIT_FAILURE; - } else - srcdev = dev; + } if (udev_builtin_hwdb_search(dev, srcdev, subsystem, prefix, filter, test) > 0) return EXIT_SUCCESS; diff --git a/src/udev/udev-event.c b/src/udev/udev-event.c index 5516a792eb..4761222786 100644 --- a/src/udev/udev-event.c +++ b/src/udev/udev-event.c @@ -389,26 +389,44 @@ static int spawn_exec(struct udev_event *event, const char *cmd, char *const argv[], char **envp, int fd_stdout, int fd_stderr) { _cleanup_close_ int fd = -1; + int r; /* discard child output or connect to pipe */ fd = open("/dev/null", O_RDWR); if (fd >= 0) { - dup2(fd, STDIN_FILENO); - if (fd_stdout < 0) - dup2(fd, STDOUT_FILENO); - if (fd_stderr < 0) - dup2(fd, STDERR_FILENO); + r = dup2(fd, STDIN_FILENO); + if (r < 0) + log_warning_errno(errno, "redirecting stdin failed: %m"); + + if (fd_stdout < 0) { + r = dup2(fd, STDOUT_FILENO); + if (r < 0) + log_warning_errno(errno, "redirecting stdout failed: %m"); + } + + if (fd_stderr < 0) { + r = dup2(fd, STDERR_FILENO); + if (r < 0) + log_warning_errno(errno, "redirecting stderr failed: %m"); + } } else - log_error_errno(errno, "open /dev/null failed: %m"); + log_warning_errno(errno, "open /dev/null failed: %m"); /* connect pipes to std{out,err} */ if (fd_stdout >= 0) { - dup2(fd_stdout, STDOUT_FILENO); - safe_close(fd_stdout); + r = dup2(fd_stdout, STDOUT_FILENO); + if (r < 0) + log_warning_errno(errno, "redirecting stdout failed: %m"); + + fd_stdout = safe_close(fd_stdout); } + if (fd_stderr >= 0) { - dup2(fd_stderr, STDERR_FILENO); - safe_close(fd_stderr); + r = dup2(fd_stderr, STDERR_FILENO); + if (r < 0) + log_warning_errno(errno, "redirecting stdout failed: %m"); + + fd_stderr = safe_close(fd_stderr); } /* terminate child in case parent goes away */ @@ -703,19 +721,13 @@ int udev_event_spawn(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, bool accept_failure, - const char *cmd, char **envp, + const char *cmd, char *result, size_t ressize) { int outpipe[2] = {-1, -1}; int errpipe[2] = {-1, -1}; pid_t pid; - char arg[UTIL_PATH_SIZE]; - char *argv[128]; - char program[UTIL_PATH_SIZE]; int err = 0; - strscpy(arg, sizeof(arg), cmd); - udev_build_argv(event->udev, arg, NULL, argv); - /* pipes from child to parent */ if (result != NULL || log_get_max_level() >= LOG_INFO) { if (pipe2(outpipe, O_NONBLOCK) != 0) { @@ -732,15 +744,14 @@ int udev_event_spawn(struct udev_event *event, } } - /* allow programs in /usr/lib/udev/ to be called without the path */ - if (argv[0][0] != '/') { - strscpyl(program, sizeof(program), UDEVLIBEXECDIR "/", argv[0], NULL); - argv[0] = program; - } - pid = fork(); switch(pid) { case 0: + { + char arg[UTIL_PATH_SIZE]; + char *argv[128]; + char program[UTIL_PATH_SIZE]; + /* child closes parent's ends of pipes */ if (outpipe[READ_END] >= 0) { close(outpipe[READ_END]); @@ -751,12 +762,22 @@ int udev_event_spawn(struct udev_event *event, errpipe[READ_END] = -1; } + strscpy(arg, sizeof(arg), cmd); + udev_build_argv(event->udev, arg, NULL, argv); + + /* allow programs in /usr/lib/udev/ to be called without the path */ + if (argv[0][0] != '/') { + strscpyl(program, sizeof(program), UDEVLIBEXECDIR "/", argv[0], NULL); + argv[0] = program; + } + log_debug("starting '%s'", cmd); - spawn_exec(event, cmd, argv, envp, + spawn_exec(event, cmd, argv, udev_device_get_properties_envp(event->dev), outpipe[WRITE_END], errpipe[WRITE_END]); - _exit(2 ); + _exit(2); + } case -1: log_error_errno(errno, "fork of '%s' failed: %m", cmd); err = -1; @@ -916,26 +937,21 @@ void udev_event_execute_run(struct udev_event *event, usec_t timeout_usec, usec_ struct udev_list_entry *list_entry; udev_list_entry_foreach(list_entry, udev_list_get_entry(&event->run_list)) { + char command[UTIL_PATH_SIZE]; const char *cmd = udev_list_entry_get_name(list_entry); enum udev_builtin_cmd builtin_cmd = udev_list_entry_get_num(list_entry); - if (builtin_cmd < UDEV_BUILTIN_MAX) { - char command[UTIL_PATH_SIZE]; + udev_event_apply_format(event, cmd, command, sizeof(command)); - udev_event_apply_format(event, cmd, command, sizeof(command)); + if (builtin_cmd < UDEV_BUILTIN_MAX) udev_builtin_run(event->dev, builtin_cmd, command, false); - } else { - char program[UTIL_PATH_SIZE]; - char **envp; - + else { if (event->exec_delay > 0) { - log_debug("delay execution of '%s'", program); + log_debug("delay execution of '%s'", command); sleep(event->exec_delay); } - udev_event_apply_format(event, cmd, program, sizeof(program)); - envp = udev_device_get_properties_envp(event->dev); - udev_event_spawn(event, timeout_usec, timeout_warn_usec, false, program, envp, NULL, 0); + udev_event_spawn(event, timeout_usec, timeout_warn_usec, false, command, NULL, 0); } } } diff --git a/src/udev/udev-rules.c b/src/udev/udev-rules.c index 8ebc061eb1..d00f90afa6 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -634,14 +634,11 @@ static int import_program_into_properties(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, const char *program) { - struct udev_device *dev = event->dev; - char **envp; char result[UTIL_LINE_SIZE]; char *line; int err; - envp = udev_device_get_properties_envp(dev); - err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, true, program, envp, result, sizeof(result)); + err = udev_event_spawn(event, timeout_usec, timeout_warn_usec, true, program, result, sizeof(result)); if (err < 0) return err; @@ -654,7 +651,7 @@ static int import_program_into_properties(struct udev_event *event, pos[0] = '\0'; pos = &pos[1]; } - import_property_from_string(dev, line); + import_property_from_string(event->dev, line); line = pos; } return 0; @@ -682,41 +679,6 @@ static int import_parent_into_properties(struct udev_device *dev, const char *fi return 0; } -#define WAIT_LOOP_PER_SECOND 50 -static int wait_for_file(struct udev_device *dev, const char *file, int timeout) { - char filepath[UTIL_PATH_SIZE]; - char devicepath[UTIL_PATH_SIZE]; - struct stat stats; - int loop = timeout * WAIT_LOOP_PER_SECOND; - - /* a relative path is a device attribute */ - devicepath[0] = '\0'; - if (file[0] != '/') { - strscpyl(devicepath, sizeof(devicepath), udev_device_get_syspath(dev), NULL); - strscpyl(filepath, sizeof(filepath), devicepath, "/", file, NULL); - file = filepath; - } - - while (--loop) { - const struct timespec duration = { 0, 1000 * 1000 * 1000 / WAIT_LOOP_PER_SECOND }; - - /* lookup file */ - if (stat(file, &stats) == 0) { - log_debug("file '%s' appeared after %i loops", file, (timeout * WAIT_LOOP_PER_SECOND) - loop-1); - return 0; - } - /* make sure, the device did not disappear in the meantime */ - if (devicepath[0] != '\0' && stat(devicepath, &stats) != 0) { - log_debug("device disappeared while waiting for '%s'", file); - return -2; - } - log_debug("wait for '%s' for %i mseconds", file, 1000 / WAIT_LOOP_PER_SECOND); - nanosleep(&duration, NULL); - } - log_debug("waiting for '%s' failed", file); - return -1; -} - static int attr_subst_subdir(char *attr, size_t len) { bool found = false; @@ -1397,15 +1359,6 @@ static int add_rule(struct udev_rules *rules, char *line, continue; } - if (streq(key, "WAIT_FOR") || streq(key, "WAIT_FOR_SYSFS")) { - if (op == OP_REMOVE) { - log_error("invalid WAIT_FOR/WAIT_FOR_SYSFS operation"); - goto invalid; - } - rule_add_key(&rule_tmp, TK_M_WAITFOR, 0, value, NULL); - continue; - } - if (streq(key, "LABEL")) { if (op == OP_REMOVE) { log_error("invalid LABEL operation"); @@ -1999,16 +1952,6 @@ int udev_rules_apply_to_event(struct udev_rules *rules, if (match_key(rules, cur, udev_device_get_driver(event->dev)) != 0) goto nomatch; break; - case TK_M_WAITFOR: { - char filename[UTIL_PATH_SIZE]; - int found; - - udev_event_apply_format(event, rules_str(rules, cur->key.value_off), filename, sizeof(filename)); - found = (wait_for_file(event->dev, filename, 10) == 0); - if (!found && (cur->key.op != OP_NOMATCH)) - goto nomatch; - break; - } case TK_M_ATTR: if (match_attr(rules, event->dev, event, cur) != 0) goto nomatch; @@ -2119,19 +2062,17 @@ int udev_rules_apply_to_event(struct udev_rules *rules, } case TK_M_PROGRAM: { char program[UTIL_PATH_SIZE]; - char **envp; char result[UTIL_LINE_SIZE]; free(event->program_result); event->program_result = NULL; udev_event_apply_format(event, rules_str(rules, cur->key.value_off), program, sizeof(program)); - envp = udev_device_get_properties_envp(event->dev); log_debug("PROGRAM '%s' %s:%u", program, rules_str(rules, rule->rule.filename_off), rule->rule.filename_line); - if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, true, program, envp, result, sizeof(result)) < 0) { + if (udev_event_spawn(event, timeout_usec, timeout_warn_usec, true, program, result, sizeof(result)) < 0) { if (cur->key.op != OP_NOMATCH) goto nomatch; } else { diff --git a/src/udev/udev.h b/src/udev/udev.h index 3dca72e499..d17fc8c1ea 100644 --- a/src/udev/udev.h +++ b/src/udev/udev.h @@ -85,8 +85,7 @@ int udev_event_spawn(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, bool accept_failure, - const char *cmd, char **envp, - char *result, size_t ressize); + const char *cmd, char *result, size_t ressize); void udev_event_execute_rules(struct udev_event *event, usec_t timeout_usec, usec_t timeout_warn_usec, struct udev_list *properties_list, diff --git a/src/udev/udevadm-trigger.c b/src/udev/udevadm-trigger.c index 11e83f355f..7af9665f8a 100644 --- a/src/udev/udevadm-trigger.c +++ b/src/udev/udevadm-trigger.c @@ -116,7 +116,7 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { } device_type = TYPE_DEVICES; const char *action = "change"; _cleanup_udev_enumerate_unref_ struct udev_enumerate *udev_enumerate = NULL; - int c; + int c, r; udev_enumerate = udev_enumerate_new(udev); if (udev_enumerate == NULL) @@ -153,28 +153,56 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { break; case 's': - udev_enumerate_add_match_subsystem(udev_enumerate, optarg); + r = udev_enumerate_add_match_subsystem(udev_enumerate, optarg); + if (r < 0) { + log_error_errno(r, "could not add subsystem match '%s': %m", optarg); + return 2; + } break; case 'S': - udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg); + r = udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg); + if (r < 0) { + log_error_errno(r, "could not add negative subsystem match '%s': %m", optarg); + return 2; + } break; case 'a': key = keyval(optarg, &val, buf, sizeof(buf)); - udev_enumerate_add_match_sysattr(udev_enumerate, key, val); + r = udev_enumerate_add_match_sysattr(udev_enumerate, key, val); + if (r < 0) { + log_error_errno(r, "could not add sysattr match '%s=%s': %m", key, val); + return 2; + } break; case 'A': key = keyval(optarg, &val, buf, sizeof(buf)); - udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val); + r = udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val); + if (r < 0) { + log_error_errno(r, "could not add negative sysattr match '%s=%s': %m", key, val); + return 2; + } break; case 'p': key = keyval(optarg, &val, buf, sizeof(buf)); - udev_enumerate_add_match_property(udev_enumerate, key, val); + r = udev_enumerate_add_match_property(udev_enumerate, key, val); + if (r < 0) { + log_error_errno(r, "could not add property match '%s=%s': %m", key, val); + return 2; + } break; case 'g': - udev_enumerate_add_match_tag(udev_enumerate, optarg); + r = udev_enumerate_add_match_tag(udev_enumerate, optarg); + if (r < 0) { + log_error_errno(r, "could not add tag match '%s': %m", optarg); + return 2; + } break; case 'y': - udev_enumerate_add_match_sysname(udev_enumerate, optarg); + r = udev_enumerate_add_match_sysname(udev_enumerate, optarg); + if (r < 0) { + log_error_errno(r, "could not add sysname match '%s': %m", optarg); + return 2; + } break; case 'b': { _cleanup_udev_device_unref_ struct udev_device *dev; @@ -185,7 +213,11 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { return 2; } - udev_enumerate_add_match_parent(udev_enumerate, dev); + r = udev_enumerate_add_match_parent(udev_enumerate, dev); + if (r < 0) { + log_error_errno(r, "could not add parent match '%s': %m", optarg); + return 2; + } break; } @@ -198,7 +230,11 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { return 2; } - udev_enumerate_add_match_parent(udev_enumerate, dev); + r = udev_enumerate_add_match_parent(udev_enumerate, dev); + if (r < 0) { + log_error_errno(r, "could not add parent match '%s': %m", optarg); + return 2; + } break; } @@ -221,7 +257,11 @@ static int adm_trigger(struct udev *udev, int argc, char *argv[]) { return 2; } - udev_enumerate_add_match_parent(udev_enumerate, dev); + r = udev_enumerate_add_match_parent(udev_enumerate, dev); + if (r < 0) { + log_error_errno(r, "could not add tag match '%s': %m", optarg); + return 2; + } } switch (device_type) { diff --git a/src/udev/udevd.c b/src/udev/udevd.c index c205f1d5ec..e27fb1fd9e 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -327,6 +327,7 @@ static void worker_spawn(Manager *manager, struct event *event) { struct udev *udev = event->udev; _cleanup_udev_monitor_unref_ struct udev_monitor *worker_monitor = NULL; pid_t pid; + int r = 0; /* listen for new events */ worker_monitor = udev_monitor_new_from_netlink(udev, NULL); @@ -334,7 +335,9 @@ static void worker_spawn(Manager *manager, struct event *event) { return; /* allow the main daemon netlink address to send devices to the worker */ udev_monitor_allow_unicast_sender(worker_monitor, manager->monitor); - udev_monitor_enable_receiving(worker_monitor); + r = udev_monitor_enable_receiving(worker_monitor); + if (r < 0) + log_error_errno(r, "worker: could not enable receiving of device: %m"); pid = fork(); switch (pid) { @@ -346,7 +349,6 @@ static void worker_spawn(Manager *manager, struct event *event) { struct epoll_event ep_signal = { .events = EPOLLIN }; struct epoll_event ep_monitor = { .events = EPOLLIN }; sigset_t mask; - int r = 0; /* take initial device from queue */ dev = event->dev; @@ -528,7 +530,6 @@ out: default: { struct worker *worker; - int r; r = worker_new(&worker, manager, worker_monitor, pid); if (r < 0) @@ -1607,8 +1608,42 @@ static int manager_new(Manager **ret, int fd_ctrl, int fd_uevent, const char *cg return 0; } -int main(int argc, char *argv[]) { +static int run(int fd_ctrl, int fd_uevent, const char *cgroup) { _cleanup_(manager_freep) Manager *manager = NULL; + int r; + + r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup); + if (r < 0) { + r = log_error_errno(r, "failed to allocate manager object: %m"); + goto exit; + } + + r = udev_rules_apply_static_dev_perms(manager->rules); + if (r < 0) + log_error_errno(r, "failed to apply permissions on static device nodes: %m"); + + (void) sd_notify(false, + "READY=1\n" + "STATUS=Processing..."); + + r = sd_event_loop(manager->event); + if (r < 0) { + log_error_errno(r, "event loop failed: %m"); + goto exit; + } + + sd_event_get_exit_code(manager->event, &r); + +exit: + sd_notify(false, + "STOPPING=1\n" + "STATUS=Shutting down..."); + if (manager) + udev_ctrl_cleanup(manager->ctrl); + return r; +} + +int main(int argc, char *argv[]) { _cleanup_free_ char *cgroup = NULL; int r, fd_ctrl, fd_uevent; @@ -1624,8 +1659,10 @@ int main(int argc, char *argv[]) { if (r < 0) log_warning_errno(r, "failed to parse kernel command line, ignoring: %m"); - if (arg_debug) + if (arg_debug) { + log_set_target(LOG_TARGET_CONSOLE); log_set_max_level(LOG_DEBUG); + } if (getuid() != 0) { r = log_error_errno(EPERM, "root privileges required"); @@ -1672,8 +1709,12 @@ int main(int argc, char *argv[]) { we only do this on systemd systems, and only if we are directly spawned by PID1. otherwise we are not guaranteed to have a dedicated cgroup */ r = cg_pid_get_path(SYSTEMD_CGROUP_CONTROLLER, 0, &cgroup); - if (r < 0) - log_warning_errno(r, "failed to get cgroup: %m"); + if (r < 0) { + if (r == -ENOENT) + log_debug_errno(r, "did not find dedicated cgroup: %m"); + else + log_warning_errno(r, "failed to get cgroup: %m"); + } } r = listen_fds(&fd_ctrl, &fd_uevent); @@ -1709,35 +1750,9 @@ int main(int argc, char *argv[]) { write_string_file("/proc/self/oom_score_adj", "-1000"); } - r = manager_new(&manager, fd_ctrl, fd_uevent, cgroup); - if (r < 0) { - r = log_error_errno(r, "failed to allocate manager object: %m"); - goto exit; - } - - r = udev_rules_apply_static_dev_perms(manager->rules); - if (r < 0) - log_error_errno(r, "failed to apply permissions on static device nodes: %m"); - - (void) sd_notify(false, - "READY=1\n" - "STATUS=Processing..."); - - r = sd_event_loop(manager->event); - if (r < 0) { - log_error_errno(r, "event loop failed: %m"); - goto exit; - } - - sd_event_get_exit_code(manager->event, &r); + r = run(fd_ctrl, fd_uevent, cgroup); exit: - sd_notify(false, - "STOPPING=1\n" - "STATUS=Shutting down..."); - - if (manager) - udev_ctrl_cleanup(manager->ctrl); mac_selinux_finish(); log_close(); return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; diff --git a/src/udev/v4l_id/Makefile b/src/udev/v4l_id/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/udev/v4l_id/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/update-done/Makefile b/src/update-done/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/update-done/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/update-utmp/Makefile b/src/update-utmp/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/update-utmp/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/user-sessions/Makefile b/src/user-sessions/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/user-sessions/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file diff --git a/src/vconsole/.gitignore b/src/vconsole/.gitignore new file mode 100644 index 0000000000..82741b2fb3 --- /dev/null +++ b/src/vconsole/.gitignore @@ -0,0 +1 @@ +/90-vconsole.rules diff --git a/src/vconsole/Makefile b/src/vconsole/Makefile new file mode 120000 index 0000000000..d0b0e8e008 --- /dev/null +++ b/src/vconsole/Makefile @@ -0,0 +1 @@ +../Makefile
\ No newline at end of file |