diff options
-rw-r--r-- | docs/.gitignore | 1 | ||||
-rw-r--r-- | man/journalctl.xml | 4 | ||||
-rw-r--r-- | man/machinectl.xml | 2 | ||||
-rw-r--r-- | man/networkctl.xml | 2 | ||||
-rw-r--r-- | man/sd_notify.xml | 2 | ||||
-rw-r--r-- | man/udev.xml | 9 | ||||
-rw-r--r-- | src/bootchart/store.c | 30 | ||||
-rw-r--r-- | src/core/main.c | 4 | ||||
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-internal.h | 25 | ||||
-rw-r--r-- | src/libsystemd/sd-netlink/netlink-message.c | 174 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 30 | ||||
-rw-r--r-- | src/sysv-generator/sysv-generator.c | 32 | ||||
-rw-r--r-- | src/udev/udev-rules.c | 54 | ||||
-rw-r--r-- | test/rule-syntax-check.py | 2 | ||||
-rw-r--r-- | test/sysv-generator-test.py | 19 |
15 files changed, 170 insertions, 220 deletions
diff --git a/docs/.gitignore b/docs/.gitignore deleted file mode 100644 index ac7af2e80e..0000000000 --- a/docs/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/html/ diff --git a/man/journalctl.xml b/man/journalctl.xml index 08de0ff068..ca933645a9 100644 --- a/man/journalctl.xml +++ b/man/journalctl.xml @@ -111,9 +111,9 @@ <para>All users are granted access to their private per-user journals. However, by default, only root and users who are members of a few special groups are granted access to the system - journal and the journals of other users. Members of the the + journal and the journals of other users. Members of the groups <literal>systemd-journal</literal>, <literal>adm</literal>, and - <literal>wheel</literal> groups can read all journal files. Note + <literal>wheel</literal> can read all journal files. Note that the two latter groups traditionally have additional privileges specified by the distribution. Members of the <literal>wheel</literal> group can often perform administrative diff --git a/man/machinectl.xml b/man/machinectl.xml index cf17349a6c..4b87870853 100644 --- a/man/machinectl.xml +++ b/man/machinectl.xml @@ -628,7 +628,7 @@ <para>Image verification is identical for raw and tar images (see above).</para> - <para>If the the downloaded image is in + <para>If the downloaded image is in <filename>.qcow2</filename> format it is converted into a raw image file before it is made available.</para> diff --git a/man/networkctl.xml b/man/networkctl.xml index 884d2005c4..388afbed93 100644 --- a/man/networkctl.xml +++ b/man/networkctl.xml @@ -64,7 +64,7 @@ state of the network links as seen by <command>systemd-networkd</command>. Please refer to <citerefentry><refentrytitle>systemd-networkd.service</refentrytitle><manvolnum>8</manvolnum></citerefentry> - for an introduction to the the basic concepts, functionality, and + for an introduction to the basic concepts, functionality, and configuration syntax.</para> </refsect1> diff --git a/man/sd_notify.xml b/man/sd_notify.xml index 87e59c9cc2..14030f56b1 100644 --- a/man/sd_notify.xml +++ b/man/sd_notify.xml @@ -197,7 +197,7 @@ <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry> for information how to enable this functionality and <citerefentry><refentrytitle>sd_watchdog_enabled</refentrytitle><manvolnum>3</manvolnum></citerefentry> - for the details of how the service can check if the the + for the details of how the service can check whether the watchdog is enabled. </para></listitem> </varlistentry> diff --git a/man/udev.xml b/man/udev.xml index 4c2e13ee7b..2e1655bf55 100644 --- a/man/udev.xml +++ b/man/udev.xml @@ -522,15 +522,6 @@ </varlistentry> <varlistentry> - <term><varname>WAIT_FOR</varname></term> - <listitem> - <para>Wait for a file to become available or until a timeout of - 10 seconds expires. The path is relative to the sysfs device; - if no path is specified, this waits for an attribute to appear.</para> - </listitem> - </varlistentry> - - <varlistentry> <term><varname>OPTIONS</varname></term> <listitem> <para>Rule and device options:</para> diff --git a/src/bootchart/store.c b/src/bootchart/store.c index 00439f0409..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; @@ -156,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"); - } + /* 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"); - n = pread(schedstat, buf, sizeof(buf) - 1, 0); - if (n <= 0) { - schedstat = safe_close(schedstat); - if (n < 0) - return -errno; - return -ENODATA; - } - - 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; @@ -238,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) @@ -427,7 +414,6 @@ schedstat_next: return -errno; } FOREACH_DIRENT(ent, taskdir, break) { - int r; int tid = -1; _cleanup_close_ int tid_schedstat = -1; long long delta_rt; 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/libsystemd/sd-netlink/netlink-internal.h b/src/libsystemd/sd-netlink/netlink-internal.h index 7290f4e875..b8a3668bfc 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 attirubte */ +}; + +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 a935b821f6..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) @@ -88,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; - type_get_type_system(nl_type, &m->container_type_system[0]); + type_get_type_system(nl_type, &m->containers[0].type_system); m->hdr->nlmsg_len = size; m->hdr->nlmsg_type = type; @@ -129,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); @@ -223,7 +223,7 @@ static int message_attribute_has_type(sd_netlink_message *m, size_t *out_size, u assert(m); - r = type_system_get_type(m->container_type_system[m->n_containers], &type, attribute_type); + r = type_system_get_type(m->containers[m->n_containers].type_system, &type, attribute_type); if (r < 0) return r; @@ -406,18 +406,18 @@ int sd_netlink_message_open_container(sd_netlink_message *m, unsigned short type 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 { - 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; @@ -427,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; } @@ -439,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; @@ -454,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; } @@ -469,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); @@ -505,7 +508,7 @@ int sd_netlink_message_read_string(sd_netlink_message *m, unsigned short type, c 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) @@ -527,7 +530,7 @@ int sd_netlink_message_read_u8(sd_netlink_message *m, unsigned short type, uint8 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)) @@ -549,7 +552,7 @@ int sd_netlink_message_read_u16(sd_netlink_message *m, unsigned short type, uint 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)) @@ -571,7 +574,7 @@ int sd_netlink_message_read_u32(sd_netlink_message *m, unsigned short type, uint 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)) @@ -593,7 +596,7 @@ int sd_netlink_message_read_ether_addr(sd_netlink_message *m, unsigned short typ 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)) @@ -615,7 +618,7 @@ int sd_netlink_message_read_cache_info(sd_netlink_message *m, unsigned short typ 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)) @@ -637,7 +640,7 @@ int sd_netlink_message_read_in_addr(sd_netlink_message *m, unsigned short type, 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)) @@ -659,7 +662,7 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, 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)) @@ -671,6 +674,40 @@ int sd_netlink_message_read_in6_addr(sd_netlink_message *m, unsigned short type, return 0; } +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; @@ -682,7 +719,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ 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_id); if (r < 0) @@ -691,7 +728,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ type = type_get_type(nl_type); if (type == NETLINK_TYPE_NESTED) { - r = type_system_get_type_system(m->container_type_system[m->n_containers], + r = type_system_get_type_system(m->containers[m->n_containers].type_system, &type_system, type_id); if (r < 0) @@ -699,7 +736,7 @@ int sd_netlink_message_enter_container(sd_netlink_message *m, unsigned short typ } 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_id); if (r < 0) @@ -744,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_id, &container); + r = netlink_message_read_internal(m, type_id, &container); if (r < 0) return r; else @@ -752,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_get_count(type_system), - 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; } @@ -773,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 --; @@ -810,41 +846,6 @@ 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 count, - struct rtattr *rta, - unsigned int rt_len) { - unsigned short type; - size_t *tb; - - tb = new0(size_t, count); - if(!tb) - return -ENOMEM; - - *rta_tb_size = count; - - 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 >= count) - 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 *nl_type; uint16_t type; @@ -859,15 +860,13 @@ 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; } @@ -886,14 +885,13 @@ int sd_netlink_message_rewind(sd_netlink_message *m) { 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_get_count(type_system), - (struct rtattr*)((uint8_t*)NLMSG_DATA(m->hdr) + NLMSG_ALIGN(size)), - NLMSG_PAYLOAD(m->hdr, 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/nspawn/nspawn.c b/src/nspawn/nspawn.c index 4cf2d14ae2..7fa098bea8 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -1074,18 +1074,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 }; @@ -4313,10 +4313,6 @@ static int outer_child( if (r < 0) return r; - r = determine_uid_shift(directory); - if (r < 0) - return r; - /* 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"); @@ -4495,6 +4491,10 @@ int main(int argc, char *argv[]) { if (r < 0) goto finish; + r = determine_uid_shift(arg_directory); + if (r < 0) + return r; + if (geteuid() != 0) { log_error("Need to be root."); r = -EPERM; diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c index 9ae518ac4a..0d246b1835 100644 --- a/src/sysv-generator/sysv-generator.c +++ b/src/sysv-generator/sysv-generator.c @@ -241,19 +241,21 @@ static bool usage_contains_reload(const char *line) { static char *sysv_translate_name(const char *name) { char *r; + _cleanup_free_ char *c; - r = new(char, strlen(name) + strlen(".service") + 1); - if (!r) - return NULL; + 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"); + r = endswith(c, ".sh"); + if (r) { + *r = '\0'; + } - return r; + if (unit_name_mangle(c, UNIT_NAME_NOGLOB, &r) >= 0) + return r; + else + return NULL; } static int sysv_translate_facility(const char *name, const char *filename, char **_r) { @@ -340,6 +342,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 +354,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 @@ -374,6 +378,10 @@ static int handle_provides(SysvStub *s, unsigned line, const char *full_text, co 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/udev/udev-rules.c b/src/udev/udev-rules.c index c3e2e211e3..d00f90afa6 100644 --- a/src/udev/udev-rules.c +++ b/src/udev/udev-rules.c @@ -679,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; @@ -1394,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"); @@ -1996,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; diff --git a/test/rule-syntax-check.py b/test/rule-syntax-check.py index 80bbe65bea..e43a3daeb3 100644 --- a/test/rule-syntax-check.py +++ b/test/rule-syntax-check.py @@ -35,7 +35,7 @@ else: no_args_tests = re.compile('(ACTION|DEVPATH|KERNELS?|NAME|SYMLINK|SUBSYSTEMS?|DRIVERS?|TAG|RESULT|TEST)\s*(?:=|!)=\s*"([^"]*)"$') args_tests = re.compile('(ATTRS?|ENV|TEST){([a-zA-Z0-9/_.*%-]+)}\s*(?:=|!)=\s*"([^"]*)"$') -no_args_assign = re.compile('(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|PROGRAM|RUN|LABEL|GOTO|WAIT_FOR|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*"([^"]*)"$') +no_args_assign = re.compile('(NAME|SYMLINK|OWNER|GROUP|MODE|TAG|PROGRAM|RUN|LABEL|GOTO|OPTIONS|IMPORT)\s*(?:\+=|:=|=)\s*"([^"]*)"$') args_assign = re.compile('(ATTR|ENV|IMPORT|RUN){([a-zA-Z0-9/_.*%-]+)}\s*(=|\+=)\s*"([^"]*)"$') result = 0 diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py index af0493b9a8..23d6646bba 100644 --- a/test/sysv-generator-test.py +++ b/test/sysv-generator-test.py @@ -190,6 +190,15 @@ class SysvGeneratorTest(unittest.TestCase): self.assert_enabled('foo.service', ['multi-user', 'graphical']) self.assertNotIn('Overwriting', err) + def test_simple_escaped(self): + '''simple service without dependencies, that requires escaping the name''' + + self.add_sysv('foo+', {}) + self.add_sysv('foo-admin', {}) + err, results = self.run_generator() + self.assertEqual(list(results), ['foo-admin.service', 'foo\\x2b.service']) + self.assertNotIn('Overwriting', err) + def test_simple_enabled_some(self): '''simple service without dependencies, enabled in some runlevels''' @@ -276,6 +285,16 @@ class SysvGeneratorTest(unittest.TestCase): 'foo.service') self.assertNotIn('Overwriting', err) + def test_provides_escaped(self): + '''a script that Provides: a name that requires escaping''' + + self.add_sysv('foo', {'Provides': 'foo foo+'}) + err, results = self.run_generator() + self.assertEqual(list(results), ['foo.service']) + self.assertEqual(os.readlink(os.path.join(self.out_dir, 'foo\\x2b.service')), + 'foo.service') + self.assertNotIn('Overwriting', err) + def test_same_provides_in_multiple_scripts(self): '''multiple init.d scripts provide the same name''' |