]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Merge pull request #1227 from intelfx/systemctl-legacy-tools-polkit
authorLennart Poettering <lennart@poettering.net>
Thu, 10 Sep 2015 17:53:31 +0000 (19:53 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 10 Sep 2015 17:53:31 +0000 (19:53 +0200)
systemctl: fix various aspects of polkit authorization in legacy tools.

62 files changed:
CODING_STYLE
TODO
coccinelle/hashmap_free.cocci [new file with mode: 0644]
coccinelle/strv_free.cocci [new file with mode: 0644]
configure.ac
hwdb/60-keyboard.hwdb
man/systemd-cgtop.xml
man/systemd-system.conf.xml
man/systemd.resource-control.xml
src/basic/cgroup-util.c
src/basic/cgroup-util.h
src/basic/copy.c
src/basic/copy.h
src/basic/util.c
src/basic/util.h
src/cgtop/cgtop.c
src/core/automount.c
src/core/cgroup.c
src/core/cgroup.h
src/core/dbus-cgroup.c
src/core/dbus-unit.c
src/core/dbus.c
src/core/device.c
src/core/execute.c
src/core/load-fragment-gperf.gperf.m4
src/core/load-fragment.c
src/core/load-fragment.h
src/core/main.c
src/core/manager.h
src/core/swap.c
src/core/unit.c
src/cryptsetup/cryptsetup-generator.c
src/import/pull-raw.c
src/journal/compress.c
src/journal/compress.h
src/journal/coredump-vacuum.c
src/journal/coredump-vacuum.h
src/journal/coredump.c
src/journal/journal-file.c
src/journal/journalctl.c
src/journal/journald-gperf.gperf
src/journal/test-compress.c
src/journal/test-coredump-vacuum.c
src/libsystemd/sd-bus/bus-creds.c
src/libsystemd/sd-bus/busctl.c
src/login/logind-user.c
src/machine/machine-dbus.c
src/machine/machinectl.c
src/nspawn/nspawn.c
src/resolve/resolved-dns-zone.c
src/resolve/resolved-link.c
src/shared/bus-util.c
src/shared/conf-parser.c
src/shared/conf-parser.h
src/shared/machine-image.c
src/shared/pager.c
src/shared/path-lookup.c
src/systemctl/systemctl.c
src/sysusers/sysusers.c
src/test/test-copy.c
src/test/test-util.c
tmpfiles.d/etc.conf.m4

index f13f9becbc0839d246ebffa44c34bcfee6963f72..98d99dcdaa086fad4b5e50e142e8a7ba2dd77bd7 100644 (file)
   always-true expression for an infinite while() loop is our
   recommendation is to simply write it without any such expression by
   using "for (;;)".
+
+- Never use the "off_t" type, and particularly avoid it in public
+  APIs. It's really weirdly defined, as it usually is 64bit and we
+  don't support it any other way, but it could in theory also be
+  32bit. Which one it is depends on a compiler switch chosen by the
+  compiled program, which hence corrupts APIs using it unless they can
+  also follow the program's choice. Moreover, in systemd we should
+  parse values the same way on all architectures and cannot expose
+  off_t values over D-Bus. To avoid any confusion regarding conversion
+  and ABIs, always use simply uint64_t directly.
diff --git a/TODO b/TODO
index 4fdecebd0fa4fbb77e78d2cc4b37242f69721fd6..04b8ff102b7594a4b3779f1f3564011d77e48adc 100644 (file)
--- a/TODO
+++ b/TODO
@@ -59,8 +59,6 @@ Features:
 
 * install: include generator dirs in unit file search paths
 
-* stop using off_t, it's a crazy type. Use uint64_t instead.
-
 * logind: follow PropertiesChanged state more closely, to deal with quick logouts and relogins
 
 * invent a better systemd-run scheme for naming scopes, that works with remoting
diff --git a/coccinelle/hashmap_free.cocci b/coccinelle/hashmap_free.cocci
new file mode 100644 (file)
index 0000000..86b9542
--- /dev/null
@@ -0,0 +1,54 @@
+@@
+expression p;
+@@
+- set_free(p);
+- p = NULL;
++ p = set_free(p);
+@@
+expression p;
+@@
+- if (p)
+-         set_free(p);
+- p = NULL;
++ p = set_free(p);
+@@
+expression p;
+@@
+- if (p) {
+-         set_free(p);
+-         p = NULL;
+- }
++ p = set_free(p);
+@@
+expression p;
+@@
+- if (p)
+-         set_free(p);
++ set_free(p);
+@@
+expression p;
+@@
+- hashmap_free(p);
+- p = NULL;
++ p = hashmap_free(p);
+@@
+expression p;
+@@
+- if (p)
+-         hashmap_free(p);
+- p = NULL;
++ p = hashmap_free(p);
+@@
+expression p;
+@@
+- if (p) {
+-         hashmap_free(p);
+-         p = NULL;
+- }
++ p = hashmap_free(p);
+@@
+expression p;
+@@
+- if (p)
+-         hashmap_free(p);
++ hashmap_free(p);
diff --git a/coccinelle/strv_free.cocci b/coccinelle/strv_free.cocci
new file mode 100644 (file)
index 0000000..0ad56f7
--- /dev/null
@@ -0,0 +1,27 @@
+@@
+expression p;
+@@
+- strv_free(p);
+- p = NULL;
++ p = strv_free(p);
+@@
+expression p;
+@@
+- if (p)
+-         strv_free(p);
+- p = NULL;
++ p = strv_free(p);
+@@
+expression p;
+@@
+- if (p) {
+-         strv_free(p);
+-         p = NULL;
+- }
++ p = strv_free(p);
+@@
+expression p;
+@@
+- if (p)
+-         strv_free(p);
++ strv_free(p);
index 2024939ad0b1eeb8493bb26a6e82e1df61c14254..aad6782e0823282a5ba2ba05310af96e95d648fb 100644 (file)
@@ -657,12 +657,17 @@ if test "x${have_smack}" = xauto; then
         have_smack=yes
 fi
 
+have_smack_run_label=no
 AC_ARG_WITH(smack-run-label,
 AS_HELP_STRING([--with-smack-run-label=STRING],
         [run systemd --system itself with a specific SMACK label]),
-        [AC_DEFINE_UNQUOTED(SMACK_RUN_LABEL, ["$withval"], [Run systemd itself with SMACK label])],
+        [AC_DEFINE_UNQUOTED(SMACK_RUN_LABEL, ["$withval"], [Run systemd itself with SMACK label]) have_smack_run_label=yes],
         [])
 
+if test "x${have_smack_run_label}" = xyes; then
+        M4_DEFINES="$M4_DEFINES -DHAVE_SMACK_RUN_LABEL"
+fi
+
 AC_ARG_WITH(smack-default-process-label,
 AS_HELP_STRING([--with-smack-default-process-label=STRING],
         [default SMACK label for executed processes]),
index 65e939262a753e2008e86d38e7390d6081770ac9..3e49449ae9c5f914101277692d69e33b72184790 100644 (file)
@@ -273,6 +273,8 @@ evdev:atkbd:dmi:bvn*:bvr*:bd*:svnDell*:pnXPS12-9Q33*:pvr*
 
 # Dell Latitude microphone mute
 evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnLatitude*
+# Dell Precision microphone mute
+evdev:name:Dell WMI hotkeys:dmi:bvn*:bvr*:bd*:svnDell*:pnPrecision*
  KEYBOARD_KEY_150=f20                                   # Mic mute toggle, should be micmute
 
 ###########################################################
index 0e0ea3ba7ab07da2745b210ca976dbf4e62b3e0e..859c1a286557bfb31c9c362ae392dfa6bae64f20 100644 (file)
         <term><option>-t</option></term>
         <term><option>--order=tasks</option></term>
 
-        <listitem><para>Order by number of processes in control group.</para></listitem>
+        <listitem><para>Order by number of tasks/processes in the control group.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         pressing the <keycap>%</keycap> key.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>-P</option></term>
+
+        <listitem><para>Count only userspace processes instead of all
+        tasks. By default all tasks are counted: each kernel thread
+        and each userspace thread individually. With this setting
+        kernel threads are excluded from the counting and each
+        userspace process only counts as one, regardless how many
+        threads it consists of. This setting may also be toggled at
+        runtime by pressing the <keycap>P</keycap> key. This option
+        may not be combined with
+        <option>-k</option>.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>-k</option></term>
 
-        <listitem><para>Include kernel threads when counting tasks in
-        control groups. By default, kernel threads are not included in
-        the count. This setting may also be toggled at runtime by
-        pressing the <keycap>k</keycap> key.</para></listitem>
+        <listitem><para>Count only userspace processes and kernel
+        threads instead of all tasks. By default all tasks are
+        counted: each kernel thread and each userspace thread
+        individually. With this setting kernel threads are included in
+        the counting and each userspace process only counts as on one,
+        regardless how many threads it consists of. This setting may
+        also be toggled at runtime by pressing the <keycap>k</keycap>
+        key. This option may not be combined with
+        <option>-P</option>.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><option>--recursive=</option></term>
 
-        <listitem><para>Controls whether the number of tasks shown for
-        a control group shall include all tasks that are contained in
-        any of the child control groups as well. Takes a boolean
-        argument, defaults to <literal>yes</literal>. If enabled the
-        tasks in child control groups are included, if disabled only
-        the tasks in the control group itself are counted. This
-        setting may also be toggled at runtime by pressing the
-        <keycap>r</keycap> key.</para></listitem>
+        <listitem><para>Controls whether the number of processes shown
+        for a control group shall include all processes that are
+        contained in any of the child control groups as well. Takes a
+        boolean argument, defaults to <literal>yes</literal>. If
+        enabled the processes in child control groups are included, if
+        disabled only the processes in the control group itself are
+        counted. This setting may also be toggled at runtime by
+        pressing the <keycap>r</keycap> key. Note that this setting
+        only applies to process counting, i.e. when the
+        <option>-P</option> or <option>-k</option> options are
+        used. It has not effect if all tasks are counted, in which
+        case the counting is always recursive.</para></listitem>
       </varlistentry>
 
       <varlistentry>
         switch.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><keycap>P</keycap></term>
+
+        <listitem><para>Toggle between counting all tasks, or only
+        userspace processes. This setting may also be controlled using
+        the <option>-P</option> command line switch (see
+        above).</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><keycap>k</keycap></term>
 
-        <listitem><para>Toggle between including or excluding kernel
-        threads in control group task counts. This setting may also be
-        controlled using the <option>-k</option> command line
-        switch.</para></listitem>
+        <listitem><para>Toggle between counting all tasks, or only
+        userspace processes and kernel threads. This setting may also
+        be controlled using the <option>-k</option> command line
+        switch (see above).</para></listitem>
       </varlistentry>
 
       <varlistentry>
         <term><keycap>r</keycap></term>
 
         <listitem><para>Toggle between recursively including or
-        excluding tasks in child control groups in control group task
-        counts. This setting may also be controlled using the
-        <option>--recursive=</option> command line
-        switch.</para></listitem>
+        excluding processes in child control groups in control group
+        process counts. This setting may also be controlled using the
+        <option>--recursive=</option> command line switch. This key is
+        not available of all tasks are counted, it is only available
+        if processes are counted, as enabled with the
+        <keycap>P</keycap> or <keycap>k</keycap>
+        keys.</para></listitem>
       </varlistentry>
 
     </variablelist>
index c06accd791ed20ad56c0694c2c158f0e21dc0242..a4ba0959eaddc265dddc2d371dc2be60204df1eb 100644 (file)
   </refnamediv>
 
   <refsynopsisdiv>
-    <para><filename>/etc/systemd/system.conf</filename></para>
-    <para><filename>/etc/systemd/system.conf.d/*.conf</filename></para>
-    <para><filename>/run/systemd/system.conf.d/*.conf</filename></para>
-    <para><filename>/usr/lib/systemd/system.conf.d/*.conf</filename></para>
-    <para><filename>/etc/systemd/user.conf</filename></para>
-    <para><filename>/etc/systemd/user.conf.d/*.conf</filename></para>
-    <para><filename>/run/systemd/user.conf.d/*.conf</filename></para>
-    <para><filename>/usr/lib/systemd/user.conf.d/*.conf</filename></para>
+    <para><filename>/etc/systemd/system.conf</filename>,
+    <filename>/etc/systemd/system.conf.d/*.conf</filename>,
+    <filename>/run/systemd/system.conf.d/*.conf</filename>,
+    <filename>/usr/lib/systemd/system.conf.d/*.conf</filename></para>
+    <para><filename>/etc/systemd/user.conf</filename>,
+    <filename>/etc/systemd/user.conf.d/*.conf</filename>,
+    <filename>/run/systemd/user.conf.d/*.conf</filename>,
+    <filename>/usr/lib/systemd/user.conf.d/*.conf</filename></para>
   </refsynopsisdiv>
 
   <refsect1>
         <term><varname>DefaultCPUAccounting=</varname></term>
         <term><varname>DefaultBlockIOAccounting=</varname></term>
         <term><varname>DefaultMemoryAccounting=</varname></term>
+        <term><varname>DefaultTasksAccounting=</varname></term>
 
         <listitem><para>Configure the default resource accounting
         settings, as configured per-unit by
         <varname>CPUAccounting=</varname>,
-        <varname>BlockIOAccounting=</varname> and
-        <varname>MemoryAccounting=</varname>. See
+        <varname>BlockIOAccounting=</varname>,
+        <varname>MemoryAccounting=</varname> and
+        <varname>TasksAccounting=</varname>. See
         <citerefentry><refentrytitle>systemd.resource-control</refentrytitle><manvolnum>5</manvolnum></citerefentry>
         for details on the per-unit settings.</para></listitem>
       </varlistentry>
index 8f4e7a3f163c610e1ba40780389e18565a561471..6b9329bbee817015004cea0c2abb6c7bf2b349b8 100644 (file)
         <listitem>
           <para>Turn on CPU usage accounting for this unit. Takes a
           boolean argument. Note that turning on CPU accounting for
-          one unit might also implicitly turn it on for all units
+          one unit will also implicitly turn it on for all units
           contained in the same slice and for all its parent slices
           and the units contained therein. The system default for this
-          setting maybe controlled with
+          setting may be controlled with
           <varname>DefaultCPUAccounting=</varname> in
           <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
           prioritizing specific services at boot-up differently than
           during normal runtime.</para>
 
-          <para>Those options imply
+          <para>These options imply
           <literal>CPUAccounting=true</literal>.</para>
         </listitem>
       </varlistentry>
         <listitem>
           <para>Turn on process and kernel memory accounting for this
           unit. Takes a boolean argument. Note that turning on memory
-          accounting for one unit might also implicitly turn it on for
-          all its parent slices. The system default for this setting
-          maybe controlled with
+          accounting for one unit will also implicitly turn it on for
+          all units contained in the same slice and for all its parent
+          slices and the units contained therein. The system default
+          for this setting may be controlled with
           <varname>DefaultMemoryAccounting=</varname> in
           <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
           memory size in bytes. If the value is suffixed with K, M, G
           or T, the specified memory size is parsed as Kilobytes,
           Megabytes, Gigabytes, or Terabytes (with the base 1024),
-          respectively. This controls the
-          <literal>memory.limit_in_bytes</literal> control group
-          attribute. For details about this control group attribute,
-          see <ulink
+          respectively. If assigned the special value
+          <literal>infinity</literal> no memory limit is applied. This
+          controls the <literal>memory.limit_in_bytes</literal>
+          control group attribute. For details about this control
+          group attribute, see <ulink
           url="https://www.kernel.org/doc/Documentation/cgroups/memory.txt">memory.txt</ulink>.</para>
 
           <para>Implies <literal>MemoryAccounting=true</literal>.</para>
         </listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>TasksAccounting=</varname></term>
+
+        <listitem>
+          <para>Turn on task accounting for this unit. Takes a
+          boolean argument. If enabled, the system manager will keep
+          track of the number of tasks in the unit. The number of
+          tasks accounted this way includes both kernel threads and
+          userspace processes, with each thread counting
+          individually. Note that turning on tasks accounting for one
+          unit will also implicitly turn it on for all units contained
+          in the same slice and for all its parent slices and the
+          units contained therein. The system default for this setting
+          may be controlled with
+          <varname>DefaultTasksAccounting=</varname> in
+          <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>TasksMax=<replaceable>N</replaceable></varname></term>
+
+        <listitem>
+          <para>Specify the maximum number of tasks that may be
+          created in the unit. This ensures that the number of tasks
+          accounted for the unit (see above) stays below a specific
+          limit. If assigned the special value
+          <literal>infinity</literal> no tasks limit is applied. This
+          controls the <literal>pids.max</literal> control group
+          attribute. For details about this control group attribute,
+          see <ulink
+          url="https://www.kernel.org/doc/Documentation/cgroups/pids.txt">pids.txt</ulink>.</para>
+
+          <para>Implies <literal>TasksAccounting=true</literal>.</para>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>BlockIOAccounting=</varname></term>
 
         <listitem>
           <para>Turn on Block IO accounting for this unit. Takes a
           boolean argument. Note that turning on block IO accounting
-          for one unit might also implicitly turn it on for all units
+          for one unit will also implicitly turn it on for all units
           contained in the same slice and all for its parent slices
           and the units contained therein. The system default for this
-          setting maybe controlled with
+          setting may be controlled with
           <varname>DefaultBlockIOAccounting=</varname> in
           <citerefentry><refentrytitle>systemd-system.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.</para>
         </listitem>
index 94a25585b260ebe38f20681f95e7109907c8307b..6099dc8721e1e9ce614414ea9de59840195fbade 100644 (file)
@@ -2018,9 +2018,10 @@ int cg_mask_supported(CGroupMask *ret) {
                         mask |= CGROUP_CONTROLLER_TO_MASK(v);
                 }
 
-                /* Currently, we only support the memory controller in
-                 * the unified hierarchy, mask everything else off. */
-                mask &= CGROUP_MASK_MEMORY;
+                /* Currently, we only support the memory and pids
+                 * controller in the unified hierarchy, mask
+                 * everything else off. */
+                mask &= CGROUP_MASK_MEMORY | CGROUP_MASK_PIDS;
 
         } else {
                 CGroupController c;
@@ -2212,6 +2213,7 @@ static const char *cgroup_controller_table[_CGROUP_CONTROLLER_MAX] = {
         [CGROUP_CONTROLLER_BLKIO] = "blkio",
         [CGROUP_CONTROLLER_MEMORY] = "memory",
         [CGROUP_CONTROLLER_DEVICES] = "devices",
+        [CGROUP_CONTROLLER_PIDS] = "pids",
 };
 
 DEFINE_STRING_TABLE_LOOKUP(cgroup_controller, CGroupController);
index 16d439fd9dd324c055f398852afb0fe3be7f4e1f..7e1b4f9c72f7bf34dcc89efae472959bfcac2741 100644 (file)
@@ -35,6 +35,7 @@ typedef enum CGroupController {
         CGROUP_CONTROLLER_BLKIO,
         CGROUP_CONTROLLER_MEMORY,
         CGROUP_CONTROLLER_DEVICES,
+        CGROUP_CONTROLLER_PIDS,
         _CGROUP_CONTROLLER_MAX,
         _CGROUP_CONTROLLER_INVALID = -1,
 } CGroupController;
@@ -48,6 +49,7 @@ typedef enum CGroupMask {
         CGROUP_MASK_BLKIO = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_BLKIO),
         CGROUP_MASK_MEMORY = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_MEMORY),
         CGROUP_MASK_DEVICES = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_DEVICES),
+        CGROUP_MASK_PIDS = CGROUP_CONTROLLER_TO_MASK(CGROUP_CONTROLLER_PIDS),
         _CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1
 } CGroupMask;
 
index cc5faa80a17e24a8714e0c633958067a637a4a20..b8cbe644d443a65e601213d0040f761892070d34 100644 (file)
@@ -29,7 +29,7 @@
 
 #define COPY_BUFFER_SIZE (16*1024)
 
-int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
+int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink) {
         bool try_sendfile = true, try_splice = true;
         int r;
 
@@ -37,7 +37,7 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
         assert(fdt >= 0);
 
         /* Try btrfs reflinks first. */
-        if (try_reflink && max_bytes == (off_t) -1) {
+        if (try_reflink && max_bytes == (uint64_t) -1) {
                 r = btrfs_reflink(fdf, fdt);
                 if (r >= 0)
                         return r;
@@ -47,12 +47,12 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
                 size_t m = COPY_BUFFER_SIZE;
                 ssize_t n;
 
-                if (max_bytes != (off_t) -1) {
+                if (max_bytes != (uint64_t) -1) {
 
                         if (max_bytes <= 0)
                                 return -EFBIG;
 
-                        if ((off_t) m > max_bytes)
+                        if ((uint64_t) m > max_bytes)
                                 m = (size_t) max_bytes;
                 }
 
@@ -105,8 +105,8 @@ int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink) {
                 }
 
         next:
-                if (max_bytes != (off_t) -1) {
-                        assert(max_bytes >= n);
+                if (max_bytes != (uint64_t) -1) {
+                        assert(max_bytes >= (uint64_t) n);
                         max_bytes -= n;
                 }
         }
@@ -152,7 +152,7 @@ static int fd_copy_regular(int df, const char *from, const struct stat *st, int
         if (fdt < 0)
                 return -errno;
 
-        r = copy_bytes(fdf, fdt, (off_t) -1, true);
+        r = copy_bytes(fdf, fdt, (uint64_t) -1, true);
         if (r < 0) {
                 unlinkat(dt, to, 0);
                 return r;
@@ -371,7 +371,7 @@ int copy_file_fd(const char *from, int fdt, bool try_reflink) {
         if (fdf < 0)
                 return -errno;
 
-        r = copy_bytes(fdf, fdt, (off_t) -1, try_reflink);
+        r = copy_bytes(fdf, fdt, (uint64_t) -1, try_reflink);
 
         (void) copy_times(fdf, fdt);
         (void) copy_xattr(fdf, fdt);
index 8de0cfba325e75767862c106e08f53c5c01eca44..ba0890b44249ea764c7eaa850e9542700024b535 100644 (file)
@@ -21,6 +21,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <inttypes.h>
 #include <stdbool.h>
 #include <sys/types.h>
 
@@ -30,6 +31,6 @@ int copy_file_atomic(const char *from, const char *to, mode_t mode, bool replace
 int copy_tree(const char *from, const char *to, bool merge);
 int copy_tree_at(int fdf, const char *from, int fdt, const char *to, bool merge);
 int copy_directory_fd(int dirfd, const char *to, bool merge);
-int copy_bytes(int fdf, int fdt, off_t max_bytes, bool try_reflink);
+int copy_bytes(int fdf, int fdt, uint64_t max_bytes, bool try_reflink);
 int copy_times(int fdf, int fdt);
 int copy_xattr(int fdf, int fdt);
index f7b2edf88cc35807a51ff7f028285db38f3dd84b..e3b2af8e02f849b8d789535de48aebaa6ba03b96 100644 (file)
@@ -2214,7 +2214,7 @@ int loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
         return 0;
 }
 
-int parse_size(const char *t, off_t base, off_t *size) {
+int parse_size(const char *t, uint64_t base, uint64_t *size) {
 
         /* Soo, sometimes we want to parse IEC binary suffixes, and
          * sometimes SI decimal suffixes. This function can parse
@@ -2242,8 +2242,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
                 { "G", 1024ULL*1024ULL*1024ULL },
                 { "M", 1024ULL*1024ULL },
                 { "K", 1024ULL },
-                { "B", 1 },
-                { "", 1 },
+                { "B", 1ULL },
+                { "",  1ULL },
         };
 
         static const struct table si[] = {
@@ -2253,8 +2253,8 @@ int parse_size(const char *t, off_t base, off_t *size) {
                 { "G", 1000ULL*1000ULL*1000ULL },
                 { "M", 1000ULL*1000ULL },
                 { "K", 1000ULL },
-                { "B", 1 },
-                { "", 1 },
+                { "B", 1ULL },
+                { "",  1ULL },
         };
 
         const struct table *table;
@@ -2276,33 +2276,32 @@ int parse_size(const char *t, off_t base, off_t *size) {
 
         p = t;
         do {
-                long long l;
-                unsigned long long l2;
+                unsigned long long l, tmp;
                 double frac = 0;
                 char *e;
                 unsigned i;
 
-                errno = 0;
-                l = strtoll(p, &e, 10);
+                p += strspn(p, WHITESPACE);
+                if (*p == '-')
+                        return -ERANGE;
 
+                errno = 0;
+                l = strtoull(p, &e, 10);
                 if (errno > 0)
                         return -errno;
-
-                if (l < 0)
-                        return -ERANGE;
-
                 if (e == p)
                         return -EINVAL;
 
                 if (*e == '.') {
                         e++;
+
+                        /* strtoull() itself would accept space/+/- */
                         if (*e >= '0' && *e <= '9') {
+                                unsigned long long l2;
                                 char *e2;
 
-                                /* strotoull itself would accept space/+/- */
                                 l2 = strtoull(e, &e2, 10);
-
-                                if (errno == ERANGE)
+                                if (errno > 0)
                                         return -errno;
 
                                 /* Ignore failure. E.g. 10.M is valid */
@@ -2315,27 +2314,27 @@ int parse_size(const char *t, off_t base, off_t *size) {
                 e += strspn(e, WHITESPACE);
 
                 for (i = start_pos; i < n_entries; i++)
-                        if (startswith(e, table[i].suffix)) {
-                                unsigned long long tmp;
-                                if ((unsigned long long) l + (frac > 0) > ULLONG_MAX / table[i].factor)
-                                        return -ERANGE;
-                                tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
-                                if (tmp > ULLONG_MAX - r)
-                                        return -ERANGE;
-
-                                r += tmp;
-                                if ((unsigned long long) (off_t) r != r)
-                                        return -ERANGE;
-
-                                p = e + strlen(table[i].suffix);
-
-                                start_pos = i + 1;
+                        if (startswith(e, table[i].suffix))
                                 break;
-                        }
 
                 if (i >= n_entries)
                         return -EINVAL;
 
+                if (l + (frac > 0) > ULLONG_MAX / table[i].factor)
+                        return -ERANGE;
+
+                tmp = l * table[i].factor + (unsigned long long) (frac * table[i].factor);
+                if (tmp > ULLONG_MAX - r)
+                        return -ERANGE;
+
+                r += tmp;
+                if ((unsigned long long) (uint64_t) r != r)
+                        return -ERANGE;
+
+                p = e + strlen(table[i].suffix);
+
+                start_pos = i + 1;
+
         } while (*p);
 
         *size = r;
@@ -3785,38 +3784,38 @@ int prot_from_flags(int flags) {
         }
 }
 
-char *format_bytes(char *buf, size_t l, off_t t) {
+char *format_bytes(char *buf, size_t l, uint64_t t) {
         unsigned i;
 
         static const struct {
                 const char *suffix;
-                off_t factor;
+                uint64_t factor;
         } table[] = {
-                { "E", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
-                { "P", 1024ULL*1024ULL*1024ULL*1024ULL*1024ULL },
-                { "T", 1024ULL*1024ULL*1024ULL*1024ULL },
-                { "G", 1024ULL*1024ULL*1024ULL },
-                { "M", 1024ULL*1024ULL },
-                { "K", 1024ULL },
+                { "E", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
+                { "P", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
+                { "T", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
+                { "G", UINT64_C(1024)*UINT64_C(1024)*UINT64_C(1024) },
+                { "M", UINT64_C(1024)*UINT64_C(1024) },
+                { "K", UINT64_C(1024) },
         };
 
-        if (t == (off_t) -1)
+        if (t == (uint64_t) -1)
                 return NULL;
 
         for (i = 0; i < ELEMENTSOF(table); i++) {
 
                 if (t >= table[i].factor) {
                         snprintf(buf, l,
-                                 "%llu.%llu%s",
-                                 (unsigned long long) (t / table[i].factor),
-                                 (unsigned long long) (((t*10ULL) / table[i].factor) % 10ULL),
+                                 "%" PRIu64 ".%" PRIu64 "%s",
+                                 t / table[i].factor,
+                                 ((t*UINT64_C(10)) / table[i].factor) % UINT64_C(10),
                                  table[i].suffix);
 
                         goto finish;
                 }
         }
 
-        snprintf(buf, l, "%lluB", (unsigned long long) t);
+        snprintf(buf, l, "%" PRIu64 "B", t);
 
 finish:
         buf[l-1] = 0;
index 5fa44b5cf31c9e86b28ce4a4448f16528f67c2da..c7dff9a86d8a3f3b4f532fda891f17e21c9c907d 100644 (file)
@@ -152,7 +152,7 @@ void close_many(const int fds[], unsigned n_fd);
 int fclose_nointr(FILE *f);
 FILE* safe_fclose(FILE *f);
 
-int parse_size(const char *t, off_t base, off_t *size);
+int parse_size(const char *t, uint64_t base, uint64_t *size);
 
 int parse_boolean(const char *v) _pure_;
 int parse_pid(const char *s, pid_t* ret_pid);
@@ -478,7 +478,7 @@ bool kexec_loaded(void);
 
 int prot_from_flags(int flags) _const_;
 
-char *format_bytes(char *buf, size_t l, off_t t);
+char *format_bytes(char *buf, size_t l, uint64_t t);
 
 int fd_wait_for_event(int fd, int event, usec_t timeout);
 
index 1c94bea31ae3050cffba07b69eb0a8a981857cf7..4786a155dad5a9f28baaed8a2994f82985c2d1aa 100644 (file)
@@ -45,7 +45,7 @@ typedef struct Group {
         bool memory_valid:1;
         bool io_valid:1;
 
-        unsigned n_tasks;
+        uint64_t n_tasks;
 
         unsigned cpu_iteration;
         nsec_t cpu_usage;
@@ -65,7 +65,12 @@ static unsigned arg_iterations = (unsigned) -1;
 static bool arg_batch = false;
 static bool arg_raw = false;
 static usec_t arg_delay = 1*USEC_PER_SEC;
-static bool arg_kernel_threads = false;
+
+enum {
+        COUNT_PIDS,
+        COUNT_USERSPACE_PROCESSES,
+        COUNT_ALL_PROCESSES,
+} arg_count = COUNT_PIDS;
 static bool arg_recursive = true;
 
 static enum {
@@ -73,7 +78,7 @@ static enum {
         ORDER_TASKS,
         ORDER_CPU,
         ORDER_MEMORY,
-        ORDER_IO
+        ORDER_IO,
 } arg_order = ORDER_CPU;
 
 static enum {
@@ -100,7 +105,7 @@ static void group_hashmap_free(Hashmap *h) {
         hashmap_free(h);
 }
 
-static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, off_t t) {
+static const char *maybe_format_bytes(char *buf, size_t l, bool is_valid, uint64_t t) {
         if (!is_valid)
                 return "-";
         if (arg_raw) {
@@ -153,7 +158,7 @@ static int process(
                 }
         }
 
-        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
+        if (streq(controller, SYSTEMD_CGROUP_CONTROLLER) && IN_SET(arg_count, COUNT_ALL_PROCESSES, COUNT_USERSPACE_PROCESSES)) {
                 _cleanup_fclose_ FILE *f = NULL;
                 pid_t pid;
 
@@ -166,7 +171,7 @@ static int process(
                 g->n_tasks = 0;
                 while (cg_read_pid(f, &pid) > 0) {
 
-                        if (!arg_kernel_threads && is_kernel_thread(pid) > 0)
+                        if (arg_count == COUNT_USERSPACE_PROCESSES && is_kernel_thread(pid) > 0)
                                 continue;
 
                         g->n_tasks++;
@@ -175,6 +180,26 @@ static int process(
                 if (g->n_tasks > 0)
                         g->n_tasks_valid = true;
 
+        } else if (streq(controller, "pids") && arg_count == COUNT_PIDS) {
+                _cleanup_free_ char *p = NULL, *v = NULL;
+
+                r = cg_get_path(controller, path, "pids.current", &p);
+                if (r < 0)
+                        return r;
+
+                r = read_one_line_file(p, &v);
+                if (r == -ENOENT)
+                        return 0;
+                if (r < 0)
+                        return r;
+
+                r = safe_atou64(v, &g->n_tasks);
+                if (r < 0)
+                        return r;
+
+                if (g->n_tasks > 0)
+                        g->n_tasks_valid = true;
+
         } else if (streq(controller, "cpuacct") && cg_unified() <= 0) {
                 _cleanup_free_ char *p = NULL, *v = NULL;
                 uint64_t new_usage;
@@ -371,6 +396,7 @@ static int refresh_one(
                         return r;
 
                 if (arg_recursive &&
+                    IN_SET(arg_count, COUNT_ALL_PROCESSES, COUNT_USERSPACE_PROCESSES) &&
                     child &&
                     child->n_tasks_valid &&
                     streq(controller, SYSTEMD_CGROUP_CONTROLLER)) {
@@ -407,6 +433,9 @@ static int refresh(const char *root, Hashmap *a, Hashmap *b, unsigned iteration)
         if (r < 0)
                 return r;
         r = refresh_one("blkio", root, a, b, iteration, 0, NULL);
+        if (r < 0)
+                return r;
+        r = refresh_one("pids", root, a, b, iteration, 0, NULL);
         if (r < 0)
                 return r;
 
@@ -549,7 +578,7 @@ static void display(Hashmap *a) {
                 printf("%s%-*s%s %s%7s%s %s%s%s %s%8s%s %s%8s%s %s%8s%s\n\n",
                        arg_order == ORDER_PATH ? ON : "", path_columns, "Control Group",
                        arg_order == ORDER_PATH ? OFF : "",
-                       arg_order == ORDER_TASKS ? ON : "", "Tasks",
+                       arg_order == ORDER_TASKS ? ON : "", arg_count == COUNT_PIDS ? "Tasks" : arg_count == COUNT_USERSPACE_PROCESSES ? "Procs" : "Proc+",
                        arg_order == ORDER_TASKS ? OFF : "",
                        arg_order == ORDER_CPU ? ON : "", buffer,
                        arg_order == ORDER_CPU ? OFF : "",
@@ -576,7 +605,7 @@ static void display(Hashmap *a) {
                 printf("%-*s", path_columns, ellipsized ?: path);
 
                 if (g->n_tasks_valid)
-                        printf(" %7u", g->n_tasks);
+                        printf(" %7" PRIu64, g->n_tasks);
                 else
                         fputs("       -", stdout);
 
@@ -602,15 +631,16 @@ static void help(void) {
                "  -h --help           Show this help\n"
                "     --version        Show package version\n"
                "  -p --order=path     Order by path\n"
-               "  -t --order=tasks    Order by number of tasks\n"
+               "  -t --order=tasks    Order by number of tasks/processes\n"
                "  -c --order=cpu      Order by CPU load (default)\n"
                "  -m --order=memory   Order by memory load\n"
                "  -i --order=io       Order by IO load\n"
                "  -r --raw            Provide raw (not human-readable) numbers\n"
                "     --cpu=percentage Show CPU usage as percentage (default)\n"
                "     --cpu=time       Show CPU usage as time\n"
-               "  -k                  Include kernel threads in task count\n"
-               "     --recursive=BOOL Sum up task count recursively\n"
+               "  -P                  Count userspace processes instead of tasks (excl. kernel)\n"
+               "  -k                  Count all processes instead of tasks (incl. kernel)\n"
+               "     --recursive=BOOL Sum up process count recursively\n"
                "  -d --delay=DELAY    Delay between updates\n"
                "  -n --iterations=N   Run for N iterations before exiting\n"
                "  -b --batch          Run in batch mode, accepting no input\n"
@@ -642,12 +672,13 @@ static int parse_argv(int argc, char *argv[]) {
                 {}
         };
 
+        bool recursive_unset = false;
         int c, r;
 
         assert(argc >= 1);
         assert(argv);
 
-        while ((c = getopt_long(argc, argv, "hptcmin:brd:k", options, NULL)) >= 0)
+        while ((c = getopt_long(argc, argv, "hptcmin:brd:kP", options, NULL)) >= 0)
 
                 switch (c) {
 
@@ -748,7 +779,11 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case 'k':
-                        arg_kernel_threads = true;
+                        arg_count = COUNT_ALL_PROCESSES;
+                        break;
+
+                case 'P':
+                        arg_count = COUNT_USERSPACE_PROCESSES;
                         break;
 
                 case ARG_RECURSIVE:
@@ -759,6 +794,7 @@ static int parse_argv(int argc, char *argv[]) {
                         }
 
                         arg_recursive = r;
+                        recursive_unset = r == 0;
                         break;
 
                 case '?':
@@ -773,9 +809,23 @@ static int parse_argv(int argc, char *argv[]) {
                 return -EINVAL;
         }
 
+        if (recursive_unset && arg_count == COUNT_PIDS) {
+                log_error("Non-recursive counting is only supported when counting processes, not tasks. Use -P or -k.");
+                return -EINVAL;
+        }
+
         return 1;
 }
 
+static const char* counting_what(void) {
+        if (arg_count == COUNT_PIDS)
+                return "tasks";
+        else if (arg_count == COUNT_ALL_PROCESSES)
+                return "all processes (incl. kernel)";
+        else
+                return "userspace processes (excl. kernel)";
+}
+
 int main(int argc, char *argv[]) {
         int r;
         Hashmap *a = NULL, *b = NULL;
@@ -783,10 +833,19 @@ int main(int argc, char *argv[]) {
         usec_t last_refresh = 0;
         bool quit = false, immediate_refresh = false;
         _cleanup_free_ char *root = NULL;
+        CGroupMask mask;
 
         log_parse_environment();
         log_open();
 
+        r = cg_mask_supported(&mask);
+        if (r < 0) {
+                log_error_errno(r, "Failed to determine supported controllers: %m");
+                goto finish;
+        }
+
+        arg_count = (mask & CGROUP_MASK_PIDS) ? COUNT_PIDS : COUNT_USERSPACE_PROCESSES;
+
         r = parse_argv(argc, argv);
         if (r <= 0)
                 goto finish;
@@ -899,15 +958,26 @@ int main(int argc, char *argv[]) {
                         break;
 
                 case 'k':
-                        arg_kernel_threads = !arg_kernel_threads;
-                        fprintf(stdout, "\nCounting kernel threads: %s.", yes_no(arg_kernel_threads));
+                        arg_count = arg_count != COUNT_ALL_PROCESSES ? COUNT_ALL_PROCESSES : COUNT_PIDS;
+                        fprintf(stdout, "\nCounting: %s.", counting_what());
+                        fflush(stdout);
+                        sleep(1);
+                        break;
+
+                case 'P':
+                        arg_count = arg_count != COUNT_USERSPACE_PROCESSES ? COUNT_USERSPACE_PROCESSES : COUNT_PIDS;
+                        fprintf(stdout, "\nCounting: %s.", counting_what());
                         fflush(stdout);
                         sleep(1);
                         break;
 
                 case 'r':
-                        arg_recursive = !arg_recursive;
-                        fprintf(stdout, "\nRecursive task counting: %s", yes_no(arg_recursive));
+                        if (arg_count == COUNT_PIDS)
+                                fprintf(stdout, "\n\aCannot toggle recursive counting, not available in task counting mode.");
+                        else {
+                                arg_recursive = !arg_recursive;
+                                fprintf(stdout, "\nRecursive process counting: %s", yes_no(arg_recursive));
+                        }
                         fflush(stdout);
                         sleep(1);
                         break;
@@ -939,9 +1009,10 @@ int main(int argc, char *argv[]) {
                 case '?':
                 case 'h':
                         fprintf(stdout,
-                                "\t<" ON "p" OFF "> By path; <" ON "t" OFF "> By tasks; <" ON "c" OFF "> By CPU; <" ON "m" OFF "> By memory; <" ON "i" OFF "> By I/O\n"
+                                "\t<" ON "p" OFF "> By path; <" ON "t" OFF "> By tasks/procs; <" ON "c" OFF "> By CPU; <" ON "m" OFF "> By memory; <" ON "i" OFF "> By I/O\n"
                                 "\t<" ON "+" OFF "> Inc. delay; <" ON "-" OFF "> Dec. delay; <" ON "%%" OFF "> Toggle time; <" ON "SPACE" OFF "> Refresh\n"
-                                "\t<" ON "k" OFF "> Count kernel threads; <" ON "r" OFF "> Count recursively; <" ON "q" OFF "> Quit");
+                                "\t<" ON "P" OFF "> Toggle count userspace processes; <" ON "k" OFF "> Toggle count all processes\n"
+                                "\t<" ON "r" OFF "> Count processes recursively; <" ON "q" OFF "> Quit");
                         fflush(stdout);
                         sleep(3);
                         break;
index 5bb61b95d3132fb809eac4325a754b976b1748da..c88e3311bcd4cc96a00e2bfa0a1c57d57cb5b27a 100644 (file)
@@ -129,10 +129,8 @@ static void automount_done(Unit *u) {
 
         a->where = mfree(a->where);
 
-        set_free(a->tokens);
-        a->tokens = NULL;
-        set_free(a->expire_tokens);
-        a->expire_tokens = NULL;
+        a->tokens = set_free(a->tokens);
+        a->expire_tokens = set_free(a->expire_tokens);
 
         a->expire_event_source = sd_event_source_unref(a->expire_event_source);
 }
index baa7cc5488444e66c13c497596e4849d30931f39..48000d4e6e365386b0a4054706e6a0a7593ea31c 100644 (file)
 #include <fcntl.h>
 #include <fnmatch.h>
 
-#include "process-util.h"
+#include "cgroup-util.h"
 #include "path-util.h"
+#include "process-util.h"
 #include "special.h"
-#include "cgroup-util.h"
+
 #include "cgroup.h"
 
 #define CGROUP_CPU_QUOTA_PERIOD_USEC ((usec_t) 100 * USEC_PER_MSEC)
@@ -41,6 +42,7 @@ void cgroup_context_init(CGroupContext *c) {
         c->memory_limit = (uint64_t) -1;
         c->blockio_weight = (unsigned long) -1;
         c->startup_blockio_weight = (unsigned long) -1;
+        c->tasks_max = (uint64_t) -1;
 
         c->cpu_quota_per_sec_usec = USEC_INFINITY;
 }
@@ -106,6 +108,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
                 "%sBlockIOWeight=%lu\n"
                 "%sStartupBlockIOWeight=%lu\n"
                 "%sMemoryLimit=%" PRIu64 "\n"
+                "%sTasksMax=%" PRIu64 "\n"
                 "%sDevicePolicy=%s\n"
                 "%sDelegate=%s\n",
                 prefix, yes_no(c->cpu_accounting),
@@ -117,6 +120,7 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) {
                 prefix, c->blockio_weight,
                 prefix, c->startup_blockio_weight,
                 prefix, c->memory_limit,
+                prefix, c->tasks_max,
                 prefix, cgroup_device_policy_to_string(c->device_policy),
                 prefix, yes_no(c->delegate));
 
@@ -466,6 +470,21 @@ void cgroup_context_apply(CGroupContext *c, CGroupMask mask, const char *path, M
                                 log_debug("Ignoring device %s while writing cgroup attribute.", a->path);
                 }
         }
+
+        if ((mask & CGROUP_MASK_PIDS) && !is_root) {
+
+                if (c->tasks_max != (uint64_t) -1) {
+                        char buf[DECIMAL_STR_MAX(uint64_t) + 2];
+
+                        sprintf(buf, "%" PRIu64 "\n", c->tasks_max);
+                        r = cg_set_attribute("pids", path, "pids.max", buf);
+                } else
+                        r = cg_set_attribute("pids", path, "pids.max", "max");
+
+                if (r < 0)
+                        log_full_errno(IN_SET(r, -ENOENT, -EROFS) ? LOG_DEBUG : LOG_WARNING, r,
+                                       "Failed to set pids.max on %s: %m", path);
+        }
 }
 
 CGroupMask cgroup_context_get_mask(CGroupContext *c) {
@@ -494,6 +513,10 @@ CGroupMask cgroup_context_get_mask(CGroupContext *c) {
             c->device_policy != CGROUP_AUTO)
                 mask |= CGROUP_MASK_DEVICES;
 
+        if (c->tasks_accounting ||
+            c->tasks_max != (uint64_t) -1)
+                mask |= CGROUP_MASK_PIDS;
+
         return mask;
 }
 
@@ -1459,6 +1482,28 @@ int unit_get_memory_current(Unit *u, uint64_t *ret) {
         return safe_atou64(v, ret);
 }
 
+int unit_get_tasks_current(Unit *u, uint64_t *ret) {
+        _cleanup_free_ char *v = NULL;
+        int r;
+
+        assert(u);
+        assert(ret);
+
+        if (!u->cgroup_path)
+                return -ENODATA;
+
+        if ((u->cgroup_realized_mask & CGROUP_MASK_PIDS) == 0)
+                return -ENODATA;
+
+        r = cg_get_attribute("pids", u->cgroup_path, "pids.current", &v);
+        if (r == -ENOENT)
+                return -ENODATA;
+        if (r < 0)
+                return r;
+
+        return safe_atou64(v, ret);
+}
+
 static int unit_get_cpu_usage_raw(Unit *u, nsec_t *ret) {
         _cleanup_free_ char *v = NULL;
         uint64_t ns;
index 438f5bf50ff20a2ab3e63bd3d91db40c018db197..3ba09d56a4f8c1b73948651c5939ea5d3e5f588b 100644 (file)
@@ -72,6 +72,7 @@ struct CGroupContext {
         bool cpu_accounting;
         bool blockio_accounting;
         bool memory_accounting;
+        bool tasks_accounting;
 
         unsigned long cpu_shares;
         unsigned long startup_cpu_shares;
@@ -88,6 +89,8 @@ struct CGroupContext {
         LIST_HEAD(CGroupDeviceAllow, device_allow);
 
         bool delegate;
+
+        uint64_t tasks_max;
 };
 
 #include "unit.h"
@@ -137,6 +140,7 @@ int unit_search_main_pid(Unit *u, pid_t *ret);
 int unit_watch_all_pids(Unit *u);
 
 int unit_get_memory_current(Unit *u, uint64_t *ret);
+int unit_get_tasks_current(Unit *u, uint64_t *ret);
 int unit_get_cpu_usage(Unit *u, nsec_t *ret);
 int unit_reset_cpu_usage(Unit *u);
 
index ba2f4e53b9e60bf96fb92ee75f30722329dba94f..94de92c3dd9a0eac768e3a59f95a34f91716d1ca 100644 (file)
@@ -168,6 +168,8 @@ const sd_bus_vtable bus_cgroup_vtable[] = {
         SD_BUS_PROPERTY("MemoryLimit", "t", NULL, offsetof(CGroupContext, memory_limit), 0),
         SD_BUS_PROPERTY("DevicePolicy", "s", property_get_cgroup_device_policy, offsetof(CGroupContext, device_policy), 0),
         SD_BUS_PROPERTY("DeviceAllow", "a(ss)", property_get_device_allow, 0, 0),
+        SD_BUS_PROPERTY("TasksAccounting", "b", bus_property_get_bool, offsetof(CGroupContext, tasks_accounting), 0),
+        SD_BUS_PROPERTY("TasksMax", "t", NULL, offsetof(CGroupContext, tasks_max), 0),
         SD_BUS_VTABLE_END
 };
 
@@ -551,7 +553,11 @@ int bus_cgroup_set_property(
                 if (mode != UNIT_CHECK) {
                         c->memory_limit = limit;
                         u->cgroup_realized_mask &= ~CGROUP_MASK_MEMORY;
-                        unit_write_drop_in_private_format(u, mode, name, "%s=%" PRIu64, name, limit);
+
+                        if (limit == (uint64_t) -1)
+                                unit_write_drop_in_private(u, mode, name, "MemoryLimit=infinity");
+                        else
+                                unit_write_drop_in_private_format(u, mode, name, "MemoryLimit=%" PRIu64, limit);
                 }
 
                 return 1;
@@ -667,6 +673,39 @@ int bus_cgroup_set_property(
 
                 return 1;
 
+        } else if (streq(name, "TasksAccounting")) {
+                int b;
+
+                r = sd_bus_message_read(message, "b", &b);
+                if (r < 0)
+                        return r;
+
+                if (mode != UNIT_CHECK) {
+                        c->tasks_accounting = b;
+                        u->cgroup_realized_mask &= ~CGROUP_MASK_PIDS;
+                        unit_write_drop_in_private(u, mode, name, b ? "TasksAccounting=yes" : "TasksAccounting=no");
+                }
+
+                return 1;
+
+        } else if (streq(name, "TasksMax")) {
+                uint64_t limit;
+
+                r = sd_bus_message_read(message, "t", &limit);
+                if (r < 0)
+                        return r;
+
+                if (mode != UNIT_CHECK) {
+                        c->tasks_max = limit;
+                        u->cgroup_realized_mask &= ~CGROUP_MASK_PIDS;
+
+                        if (limit == (uint64_t) -1)
+                                unit_write_drop_in_private(u, mode, name, "TasksMax=infinity");
+                        else
+                                unit_write_drop_in_private_format(u, mode, name, "TasksMax=%" PRIu64, limit);
+                }
+
+                return 1;
         }
 
         if (u->transient && u->load_state == UNIT_STUB) {
index f9275ed935f00d08452f48a6d90f6fb20c0f4009..f7e9795928b7bca94588e1552f851b36ed229178 100644 (file)
@@ -736,6 +736,30 @@ static int property_get_current_memory(
         return sd_bus_message_append(reply, "t", sz);
 }
 
+static int property_get_current_tasks(
+                sd_bus *bus,
+                const char *path,
+                const char *interface,
+                const char *property,
+                sd_bus_message *reply,
+                void *userdata,
+                sd_bus_error *error) {
+
+        uint64_t cn = (uint64_t) -1;
+        Unit *u = userdata;
+        int r;
+
+        assert(bus);
+        assert(reply);
+        assert(u);
+
+        r = unit_get_tasks_current(u, &cn);
+        if (r < 0 && r != -ENODATA)
+                log_unit_warning_errno(u, r, "Failed to get pids.current attribute: %m");
+
+        return sd_bus_message_append(reply, "t", cn);
+}
+
 static int property_get_cpu_usage(
                 sd_bus *bus,
                 const char *path,
@@ -796,6 +820,7 @@ const sd_bus_vtable bus_unit_cgroup_vtable[] = {
         SD_BUS_PROPERTY("ControlGroup", "s", property_get_cgroup, 0, 0),
         SD_BUS_PROPERTY("MemoryCurrent", "t", property_get_current_memory, 0, 0),
         SD_BUS_PROPERTY("CPUUsageNSec", "t", property_get_cpu_usage, 0, 0),
+        SD_BUS_PROPERTY("TasksCurrent", "t", property_get_current_tasks, 0, 0),
         SD_BUS_VTABLE_END
 };
 
index 0a2180c6a7e54d044008fd36534fd343af83006a..2d6a1ff8360fa1f98a1be7703282c2153ca2137d 100644 (file)
@@ -1055,12 +1055,10 @@ void bus_done(Manager *m) {
         while ((b = set_steal_first(m->private_buses)))
                 destroy_bus(m, &b);
 
-        set_free(m->private_buses);
-        m->private_buses = NULL;
+        m->private_buses = set_free(m->private_buses);
 
         m->subscribed = sd_bus_track_unref(m->subscribed);
-        strv_free(m->deserialized_subscribed);
-        m->deserialized_subscribed = NULL;
+        m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
 
         if (m->private_listen_event_source)
                 m->private_listen_event_source = sd_event_source_unref(m->private_listen_event_source);
@@ -1191,8 +1189,7 @@ int bus_track_coldplug(Manager *m, sd_bus_track **t, char ***l) {
                 }
         }
 
-        strv_free(*l);
-        *l = NULL;
+        *l = strv_free(*l);
 
         return r;
 }
index 7fdfacfddfbeecfe38bd246cf3b99529cae99b8c..0b545186919ef0eb2ede2425eb2b82f843098687 100644 (file)
@@ -594,8 +594,7 @@ static void device_shutdown(Manager *m) {
                 m->udev_monitor = NULL;
         }
 
-        hashmap_free(m->devices_by_sysfs);
-        m->devices_by_sysfs = NULL;
+        m->devices_by_sysfs = hashmap_free(m->devices_by_sysfs);
 }
 
 static int device_enumerate(Manager *m) {
index 6abb0a5d5dbbc929ad6ae9e80a97326a0c1984c4..d1acda6682e24af3c14e6ee9ddb1a852e0a0a6c4 100644 (file)
@@ -1992,11 +1992,8 @@ void exec_context_done(ExecContext *c) {
 
         assert(c);
 
-        strv_free(c->environment);
-        c->environment = NULL;
-
-        strv_free(c->environment_files);
-        c->environment_files = NULL;
+        c->environment = strv_free(c->environment);
+        c->environment_files = strv_free(c->environment_files);
 
         for (l = 0; l < ELEMENTSOF(c->rlimit); l++)
                 c->rlimit[l] = mfree(c->rlimit[l]);
@@ -2008,8 +2005,7 @@ void exec_context_done(ExecContext *c) {
         c->user = mfree(c->user);
         c->group = mfree(c->group);
 
-        strv_free(c->supplementary_groups);
-        c->supplementary_groups = NULL;
+        c->supplementary_groups = strv_free(c->supplementary_groups);
 
         c->pam_name = mfree(c->pam_name);
 
@@ -2018,14 +2014,9 @@ void exec_context_done(ExecContext *c) {
                 c->capabilities = NULL;
         }
 
-        strv_free(c->read_only_dirs);
-        c->read_only_dirs = NULL;
-
-        strv_free(c->read_write_dirs);
-        c->read_write_dirs = NULL;
-
-        strv_free(c->inaccessible_dirs);
-        c->inaccessible_dirs = NULL;
+        c->read_only_dirs = strv_free(c->read_only_dirs);
+        c->read_write_dirs = strv_free(c->read_write_dirs);
+        c->inaccessible_dirs = strv_free(c->inaccessible_dirs);
 
         if (c->cpuset)
                 CPU_FREE(c->cpuset);
@@ -2034,17 +2025,11 @@ void exec_context_done(ExecContext *c) {
         c->selinux_context = mfree(c->selinux_context);
         c->apparmor_profile = mfree(c->apparmor_profile);
 
-        set_free(c->syscall_filter);
-        c->syscall_filter = NULL;
+        c->syscall_filter = set_free(c->syscall_filter);
+        c->syscall_archs = set_free(c->syscall_archs);
+        c->address_families = set_free(c->address_families);
 
-        set_free(c->syscall_archs);
-        c->syscall_archs = NULL;
-
-        set_free(c->address_families);
-        c->address_families = NULL;
-
-        strv_free(c->runtime_directory);
-        c->runtime_directory = NULL;
+        c->runtime_directory = strv_free(c->runtime_directory);
 
         bus_endpoint_free(c->bus_endpoint);
         c->bus_endpoint = NULL;
@@ -2079,8 +2064,7 @@ void exec_command_done(ExecCommand *c) {
 
         c->path = mfree(c->path);
 
-        strv_free(c->argv);
-        c->argv = NULL;
+        c->argv = strv_free(c->argv);
 }
 
 void exec_command_done_array(ExecCommand *c, unsigned n) {
index edd55b9e4562bfcdfddad5ebb03bbcee7deb7f84..e056fd863c9379d7ca276440e5d139bf706df0e6 100644 (file)
@@ -124,6 +124,8 @@ $1.StartupBlockIOWeight,         config_parse_blockio_weight,        0,
 $1.BlockIODeviceWeight,          config_parse_blockio_device_weight, 0,                             offsetof($1, cgroup_context)
 $1.BlockIOReadBandwidth,         config_parse_blockio_bandwidth,     0,                             offsetof($1, cgroup_context)
 $1.BlockIOWriteBandwidth,        config_parse_blockio_bandwidth,     0,                             offsetof($1, cgroup_context)
+$1.TasksAccounting,              config_parse_bool,                  0,                             offsetof($1, cgroup_context.tasks_accounting)
+$1.TasksMax,                     config_parse_tasks_max,             0,                             offsetof($1, cgroup_context)
 $1.Delegate,                     config_parse_bool,                  0,                             offsetof($1, cgroup_context.delegate)'
 )m4_dnl
 Unit.Description,                config_parse_unit_string_printf,    0,                             offsetof(Unit, description)
index b695c57da8e441acaf315e61e469e99d4a7e52dd..f7a8539910d1f1321daf59c8326c7b8026ecfef9 100644 (file)
@@ -1888,8 +1888,7 @@ int config_parse_unit_env_file(const char *unit,
 
         if (isempty(rvalue)) {
                 /* Empty assignment frees the list */
-                strv_free(*env);
-                *env = NULL;
+                *env = strv_free(*env);
                 return 0;
         }
 
@@ -1937,8 +1936,7 @@ int config_parse_environ(const char *unit,
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                strv_free(*env);
-                *env = NULL;
+                *env = strv_free(*env);
                 return 0;
         }
 
@@ -2245,8 +2243,7 @@ int config_parse_documentation(const char *unit,
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                strv_free(u->documentation);
-                u->documentation = NULL;
+                u->documentation = strv_free(u->documentation);
                 return 0;
         }
 
@@ -2305,8 +2302,7 @@ int config_parse_syscall_filter(
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                set_free(c->syscall_filter);
-                c->syscall_filter = NULL;
+                c->syscall_filter = set_free(c->syscall_filter);
                 c->syscall_whitelist = false;
                 return 0;
         }
@@ -2404,8 +2400,7 @@ int config_parse_syscall_archs(
         int r;
 
         if (isempty(rvalue)) {
-                set_free(*archs);
-                *archs = NULL;
+                *archs = set_free(*archs);
                 return 0;
         }
 
@@ -2501,8 +2496,7 @@ int config_parse_address_families(
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                set_free(c->address_families);
-                c->address_families = NULL;
+                c->address_families = set_free(c->address_families);
                 c->address_families_whitelist = false;
                 return 0;
         }
@@ -2689,24 +2683,51 @@ int config_parse_memory_limit(
                 void *userdata) {
 
         CGroupContext *c = data;
-        off_t bytes;
+        uint64_t bytes;
         int r;
 
-        if (isempty(rvalue)) {
+        if (isempty(rvalue) || streq(rvalue, "infinity")) {
                 c->memory_limit = (uint64_t) -1;
                 return 0;
         }
 
-        assert_cc(sizeof(uint64_t) == sizeof(off_t));
-
         r = parse_size(rvalue, 1024, &bytes);
-        if (r < 0) {
-                log_syntax(unit, LOG_ERR, filename, line, EINVAL,
-                           "Memory limit '%s' invalid. Ignoring.", rvalue);
+        if (r < 0 || bytes < 1) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Memory limit '%s' invalid. Ignoring.", rvalue);
+                return 0;
+        }
+
+        c->memory_limit = bytes;
+        return 0;
+}
+
+int config_parse_tasks_max(
+                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) {
+
+        CGroupContext *c = data;
+        uint64_t u;
+        int r;
+
+        if (isempty(rvalue) || streq(rvalue, "infinity")) {
+                c->tasks_max = (uint64_t) -1;
+                return 0;
+        }
+
+        r = safe_atou64(rvalue, &u);
+        if (r < 0 || u < 1) {
+                log_syntax(unit, LOG_ERR, filename, line, EINVAL, "Maximum tasks value '%s' invalid. Ignoring.", rvalue);
                 return 0;
         }
 
-        c->memory_limit = (uint64_t) bytes;
         return 0;
 }
 
@@ -2893,7 +2914,7 @@ int config_parse_blockio_bandwidth(
         CGroupBlockIODeviceBandwidth *b;
         CGroupContext *c = data;
         const char *bandwidth;
-        off_t bytes;
+        uint64_t bytes;
         bool read;
         size_t n;
         int r;
@@ -2947,7 +2968,7 @@ int config_parse_blockio_bandwidth(
 
         b->path = path;
         path = NULL;
-        b->bandwidth = (uint64_t) bytes;
+        b->bandwidth = bytes;
         b->read = read;
 
         LIST_PREPEND(device_bandwidths, c->blockio_device_bandwidths, b);
@@ -3011,8 +3032,7 @@ int config_parse_runtime_directory(
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                strv_free(*rt);
-                *rt = NULL;
+                *rt = strv_free(*rt);
                 return 0;
         }
 
@@ -3140,8 +3160,7 @@ int config_parse_namespace_path_strv(
 
         if (isempty(rvalue)) {
                 /* Empty assignment resets the list */
-                strv_free(*sv);
-                *sv = NULL;
+                *sv = strv_free(*sv);
                 return 0;
         }
 
@@ -3622,7 +3641,7 @@ void unit_dump_config_items(FILE *f) {
                 { config_parse_int,                   "INTEGER" },
                 { config_parse_unsigned,              "UNSIGNED" },
                 { config_parse_iec_size,              "SIZE" },
-                { config_parse_iec_off,               "SIZE" },
+                { config_parse_iec_uint64,            "SIZE" },
                 { config_parse_si_size,               "SIZE" },
                 { config_parse_bool,                  "BOOLEAN" },
                 { config_parse_string,                "STRING" },
index 1d128716c4d3b67d938394c4a86f357df9943185..638b343a6eb683f9b59c34d40ff402c60265ac37 100644 (file)
@@ -84,6 +84,7 @@ int config_parse_environ(const char *unit, const char *filename, unsigned line,
 int config_parse_unit_slice(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);
 int config_parse_cpu_shares(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);
 int config_parse_memory_limit(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);
+int config_parse_tasks_max(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);
 int config_parse_device_policy(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);
 int config_parse_device_allow(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);
 int config_parse_blockio_weight(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);
index be95dc68b25c95a46276587e14876ccd986fce85..200fe740dab4fccf41c9a8023eadef519d7bbc0c 100644 (file)
@@ -114,6 +114,7 @@ static FILE* arg_serialization = NULL;
 static bool arg_default_cpu_accounting = false;
 static bool arg_default_blockio_accounting = false;
 static bool arg_default_memory_accounting = false;
+static bool arg_default_tasks_accounting = false;
 
 static void nop_handler(int sig) {}
 
@@ -676,6 +677,7 @@ static int parse_config_file(void) {
                 { "Manager", "DefaultCPUAccounting",      config_parse_bool,             0, &arg_default_cpu_accounting            },
                 { "Manager", "DefaultBlockIOAccounting",  config_parse_bool,             0, &arg_default_blockio_accounting        },
                 { "Manager", "DefaultMemoryAccounting",   config_parse_bool,             0, &arg_default_memory_accounting         },
+                { "Manager", "DefaultTasksAccounting",    config_parse_bool,             0, &arg_default_tasks_accounting          },
                 {}
         };
 
@@ -704,6 +706,7 @@ static void manager_set_defaults(Manager *m) {
         m->default_cpu_accounting = arg_default_cpu_accounting;
         m->default_blockio_accounting = arg_default_blockio_accounting;
         m->default_memory_accounting = arg_default_memory_accounting;
+        m->default_tasks_accounting = arg_default_tasks_accounting;
 
         manager_set_default_rlimits(m, arg_default_rlimit);
         manager_environment_add(m, NULL, arg_default_environment);
@@ -1846,8 +1849,7 @@ finish:
 
         arg_default_environment = strv_free(arg_default_environment);
 
-        set_free(arg_syscall_archs);
-        arg_syscall_archs = NULL;
+        arg_syscall_archs = set_free(arg_syscall_archs);
 
         mac_selinux_finish();
 
index 9956cb7700dbaa6bc47d9fd22d340bf35fe61377..78a0e50a33624971b370b7ee76377907812a286f 100644 (file)
@@ -256,6 +256,7 @@ struct Manager {
         bool default_cpu_accounting;
         bool default_memory_accounting;
         bool default_blockio_accounting;
+        bool default_tasks_accounting;
 
         usec_t default_timer_accuracy_usec;
 
index 311ce7ee04eab2c227b348ecfdf5827a661bab5b..bef457069fb601241384a8880e1c87e2c299c536 100644 (file)
@@ -1254,8 +1254,7 @@ static void swap_shutdown(Manager *m) {
 
         m->proc_swaps = safe_fclose(m->proc_swaps);
 
-        hashmap_free(m->swaps_by_devnode);
-        m->swaps_by_devnode = NULL;
+        m->swaps_by_devnode = hashmap_free(m->swaps_by_devnode);
 }
 
 static int swap_enumerate(Manager *m) {
index 24a6747b1085c1371d2e23e27bac0baf090325c2..2ebfb09a7a02109a96affa5cedad6782190ef230 100644 (file)
@@ -125,6 +125,7 @@ static void unit_init(Unit *u) {
                 cc->cpu_accounting = u->manager->default_cpu_accounting;
                 cc->blockio_accounting = u->manager->default_blockio_accounting;
                 cc->memory_accounting = u->manager->default_memory_accounting;
+                cc->tasks_accounting = u->manager->default_tasks_accounting;
         }
 
         ec = unit_get_exec_context(u);
@@ -445,8 +446,7 @@ static void unit_free_requires_mounts_for(Unit *u) {
                 }
         }
 
-        strv_free(u->requires_mounts_for);
-        u->requires_mounts_for = NULL;
+        u->requires_mounts_for = strv_free(u->requires_mounts_for);
 }
 
 static void unit_done(Unit *u) {
@@ -674,8 +674,7 @@ static void merge_dependencies(Unit *u, Unit *other, const char *other_id, UnitD
         /* The move cannot fail. The caller must have performed a reservation. */
         assert_se(complete_move(&u->dependencies[d], &other->dependencies[d]) == 0);
 
-        set_free(other->dependencies[d]);
-        other->dependencies[d] = NULL;
+        other->dependencies[d] = set_free(other->dependencies[d]);
 }
 
 int unit_merge(Unit *u, Unit *other) {
index 6fad8ad80c1d48af3a6f67aec31b6e128702fa7c..ab91afec4d1e96374faecd389d01d1744eb6fd8f 100644 (file)
@@ -330,7 +330,7 @@ static int parse_proc_cmdline_item(const char *key, const char *value) {
                         free(d->keyfile);
                         d->keyfile = uuid_value;
                         uuid_value = NULL;
-                } else if (free_and_strdup(&arg_default_keyfile, value))
+                } else if (free_and_strdup(&arg_default_keyfile, value) < 0)
                         return log_oom();
 
         } else if (STR_IN_SET(key, "luks.name", "rd.luks.name") && value) {
index 44e029ef98fdf5242f4c0c10690fa75e101e884a..0e77197e34e7048e05ccb5336164426eb4548a53 100644 (file)
@@ -314,7 +314,7 @@ static int raw_pull_make_local_copy(RawPull *i) {
         if (r < 0)
                 log_warning_errno(errno, "Failed to set file attributes on %s: %m", tp);
 
-        r = copy_bytes(i->raw_job->disk_fd, dfd, (off_t) -1, true);
+        r = copy_bytes(i->raw_job->disk_fd, dfd, (uint64_t) -1, true);
         if (r < 0) {
                 unlink(tp);
                 return log_error_errno(r, "Failed to make writable copy of image: %m");
index 383f6a6e9665b84ac280b9d3c57e8f0f847c4f70..c66043e50364d65638d15e0fbcfa1cdbc076383c 100644 (file)
@@ -342,11 +342,10 @@ int decompress_startswith(int compression,
                 return -EBADMSG;
 }
 
-int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
+int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
 #ifdef HAVE_XZ
         _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
         lzma_ret ret;
-
         uint8_t buf[BUFSIZ], out[BUFSIZ];
         lzma_action action = LZMA_RUN;
 
@@ -364,8 +363,8 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
                         size_t m = sizeof(buf);
                         ssize_t n;
 
-                        if (max_bytes != -1 && m > (size_t) max_bytes)
-                                m = max_bytes;
+                        if (max_bytes != (uint64_t) -1 && (uint64_t) m > max_bytes)
+                                m = (size_t) max_bytes;
 
                         n = read(fdf, buf, m);
                         if (n < 0)
@@ -376,8 +375,8 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
                                 s.next_in = buf;
                                 s.avail_in = n;
 
-                                if (max_bytes != -1) {
-                                        assert(max_bytes >= n);
+                                if (max_bytes != (uint64_t) -1) {
+                                        assert(max_bytes >= (uint64_t) n);
                                         max_bytes -= n;
                                 }
                         }
@@ -419,7 +418,7 @@ int compress_stream_xz(int fdf, int fdt, off_t max_bytes) {
 
 #define LZ4_BUFSIZE (512*1024)
 
-int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
+int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
 
 #ifdef HAVE_LZ4
 
@@ -445,8 +444,8 @@ int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
                 int r;
 
                 m = LZ4_BUFSIZE;
-                if (max_bytes != -1 && m > (size_t) max_bytes - total_in)
-                        m = max_bytes - total_in;
+                if (max_bytes != (uint64_t) -1 && (uint64_t) m > (max_bytes - total_in))
+                        m = (size_t) (max_bytes - total_in);
 
                 n = read(fdf, buf, m);
                 if (n < 0)
@@ -497,7 +496,7 @@ int compress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
 #endif
 }
 
-int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) {
+int decompress_stream_xz(int fdf, int fdt, uint64_t max_bytes) {
 
 #ifdef HAVE_XZ
         _cleanup_(lzma_end) lzma_stream s = LZMA_STREAM_INIT;
@@ -546,8 +545,8 @@ int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) {
 
                         n = sizeof(out) - s.avail_out;
 
-                        if (max_bytes != -1) {
-                                if (max_bytes < n)
+                        if (max_bytes != (uint64_t) -1) {
+                                if (max_bytes < (uint64_t) n)
                                         return -EFBIG;
 
                                 max_bytes -= n;
@@ -572,7 +571,7 @@ int decompress_stream_xz(int fdf, int fdt, off_t max_bytes) {
 #endif
 }
 
-int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
+int decompress_stream_lz4(int fdf, int fdt, uint64_t max_bytes) {
 
 #ifdef HAVE_LZ4
         _cleanup_free_ char *buf = NULL, *out = NULL;
@@ -626,8 +625,8 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
 
                 total_out += r;
 
-                if (max_bytes != -1 && total_out > (size_t) max_bytes) {
-                        log_debug("Decompressed stream longer than %zd bytes", max_bytes);
+                if (max_bytes != (uint64_t) -1 && (uint64_t) total_out > max_bytes) {
+                        log_debug("Decompressed stream longer than %" PRIu64 " bytes", max_bytes);
                         return -EFBIG;
                 }
 
@@ -647,7 +646,7 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_bytes) {
 #endif
 }
 
-int decompress_stream(const char *filename, int fdf, int fdt, off_t max_bytes) {
+int decompress_stream(const char *filename, int fdf, int fdt, uint64_t max_bytes) {
 
         if (endswith(filename, ".lz4"))
                 return decompress_stream_lz4(fdf, fdt, max_bytes);
index 6294f16faad8a099f25cf107ba92f18fec46b739..9a065eb763baca54721e9950bb72260518d72a30 100644 (file)
@@ -67,11 +67,11 @@ int decompress_startswith(int compression,
                           const void *prefix, size_t prefix_len,
                           uint8_t extra);
 
-int compress_stream_xz(int fdf, int fdt, off_t max_bytes);
-int compress_stream_lz4(int fdf, int fdt, off_t max_bytes);
+int compress_stream_xz(int fdf, int fdt, uint64_t max_bytes);
+int compress_stream_lz4(int fdf, int fdt, uint64_t max_bytes);
 
-int decompress_stream_xz(int fdf, int fdt, off_t max_size);
-int decompress_stream_lz4(int fdf, int fdt, off_t max_size);
+int decompress_stream_xz(int fdf, int fdt, uint64_t max_size);
+int decompress_stream_lz4(int fdf, int fdt, uint64_t max_size);
 
 #ifdef HAVE_LZ4
 #  define compress_stream compress_stream_lz4
@@ -81,4 +81,4 @@ int decompress_stream_lz4(int fdf, int fdt, off_t max_size);
 #  define COMPRESSED_EXT ".xz"
 #endif
 
-int decompress_stream(const char *filename, int fdf, int fdt, off_t max_bytes);
+int decompress_stream(const char *filename, int fdf, int fdt, uint64_t max_bytes);
index c0347ef5690e4f4ebc7e75139e16b3a55e0c95a5..efe418615a6cd26c9bf5217e65bc4d15c7ecc8cd 100644 (file)
 
 #include "coredump-vacuum.h"
 
-#define DEFAULT_MAX_USE_LOWER (off_t) (1ULL*1024ULL*1024ULL)           /* 1 MiB */
-#define DEFAULT_MAX_USE_UPPER (off_t) (4ULL*1024ULL*1024ULL*1024ULL)   /* 4 GiB */
-#define DEFAULT_KEEP_FREE_UPPER (off_t) (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
-#define DEFAULT_KEEP_FREE (off_t) (1024ULL*1024ULL)                    /* 1 MB */
+#define DEFAULT_MAX_USE_LOWER (uint64_t) (1ULL*1024ULL*1024ULL)           /* 1 MiB */
+#define DEFAULT_MAX_USE_UPPER (uint64_t) (4ULL*1024ULL*1024ULL*1024ULL)   /* 4 GiB */
+#define DEFAULT_KEEP_FREE_UPPER (uint64_t) (4ULL*1024ULL*1024ULL*1024ULL) /* 4 GiB */
+#define DEFAULT_KEEP_FREE (uint64_t) (1024ULL*1024ULL)                    /* 1 MB */
 
 struct vacuum_candidate {
         unsigned n_files;
@@ -82,8 +82,8 @@ static int uid_from_file_name(const char *filename, uid_t *uid) {
         return parse_uid(u, uid);
 }
 
-static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use) {
-        off_t fs_size = 0, fs_free = (off_t) -1;
+static bool vacuum_necessary(int fd, uint64_t sum, uint64_t keep_free, uint64_t max_use) {
+        uint64_t fs_size = 0, fs_free = (uint64_t) -1;
         struct statvfs sv;
 
         assert(fd >= 0);
@@ -93,7 +93,7 @@ static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use)
                 fs_free = sv.f_frsize * sv.f_bfree;
         }
 
-        if (max_use == (off_t) -1) {
+        if (max_use == (uint64_t) -1) {
 
                 if (fs_size > 0) {
                         max_use = PAGE_ALIGN(fs_size / 10); /* 10% */
@@ -111,7 +111,7 @@ static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use)
         if (max_use > 0 && sum > max_use)
                 return true;
 
-        if (keep_free == (off_t) -1) {
+        if (keep_free == (uint64_t) -1) {
 
                 if (fs_size > 0) {
                         keep_free = PAGE_ALIGN((fs_size * 3) / 20); /* 15% */
@@ -129,7 +129,7 @@ static bool vacuum_necessary(int fd, off_t sum, off_t keep_free, off_t max_use)
         return false;
 }
 
-int coredump_vacuum(int exclude_fd, off_t keep_free, off_t max_use) {
+int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use) {
         _cleanup_closedir_ DIR *d = NULL;
         struct stat exclude_st;
         int r;
@@ -161,7 +161,7 @@ int coredump_vacuum(int exclude_fd, off_t keep_free, off_t max_use) {
                 _cleanup_(vacuum_candidate_hasmap_freep) Hashmap *h = NULL;
                 struct vacuum_candidate *worst = NULL;
                 struct dirent *de;
-                off_t sum = 0;
+                uint64_t sum = 0;
 
                 rewinddir(d);
 
index 7ad4399305372943f92528e634a9f753ffc95a38..7779c975746b940f75630d016a308dba1bd9527d 100644 (file)
@@ -21,6 +21,7 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#include <inttypes.h>
 #include <sys/types.h>
 
-int coredump_vacuum(int exclude_fd, off_t keep_free, off_t max_use);
+int coredump_vacuum(int exclude_fd, uint64_t keep_free, uint64_t max_use);
index 7d94b145c960fd4da24bb5246eac8ed583d53db6..e1e66b982623acdff0e324fc2e2b779ac371ddfa 100644 (file)
@@ -51,7 +51,7 @@
 #include "process-util.h"
 
 /* The maximum size up to which we process coredumps */
-#define PROCESS_SIZE_MAX ((off_t) (2LLU*1024LLU*1024LLU*1024LLU))
+#define PROCESS_SIZE_MAX ((uint64_t) (2LLU*1024LLU*1024LLU*1024LLU))
 
 /* The maximum size up to which we leave the coredump around on
  * disk */
@@ -97,21 +97,21 @@ static DEFINE_CONFIG_PARSE_ENUM(config_parse_coredump_storage, coredump_storage,
 
 static CoredumpStorage arg_storage = COREDUMP_STORAGE_EXTERNAL;
 static bool arg_compress = true;
-static off_t arg_process_size_max = PROCESS_SIZE_MAX;
-static off_t arg_external_size_max = EXTERNAL_SIZE_MAX;
+static uint64_t arg_process_size_max = PROCESS_SIZE_MAX;
+static uint64_t arg_external_size_max = EXTERNAL_SIZE_MAX;
 static size_t arg_journal_size_max = JOURNAL_SIZE_MAX;
-static off_t arg_keep_free = (off_t) -1;
-static off_t arg_max_use = (off_t) -1;
+static uint64_t arg_keep_free = (uint64_t) -1;
+static uint64_t arg_max_use = (uint64_t) -1;
 
 static int parse_config(void) {
         static const ConfigTableItem items[] = {
                 { "Coredump", "Storage",          config_parse_coredump_storage,  0, &arg_storage           },
                 { "Coredump", "Compress",         config_parse_bool,              0, &arg_compress          },
-                { "Coredump", "ProcessSizeMax",   config_parse_iec_off,           0, &arg_process_size_max  },
-                { "Coredump", "ExternalSizeMax",  config_parse_iec_off,           0, &arg_external_size_max },
+                { "Coredump", "ProcessSizeMax",   config_parse_iec_uint64,        0, &arg_process_size_max  },
+                { "Coredump", "ExternalSizeMax",  config_parse_iec_uint64,        0, &arg_external_size_max },
                 { "Coredump", "JournalSizeMax",   config_parse_iec_size,          0, &arg_journal_size_max  },
-                { "Coredump", "KeepFree",         config_parse_iec_off,           0, &arg_keep_free         },
-                { "Coredump", "MaxUse",           config_parse_iec_off,           0, &arg_max_use           },
+                { "Coredump", "KeepFree",         config_parse_iec_uint64,        0, &arg_keep_free         },
+                { "Coredump", "MaxUse",           config_parse_iec_uint64,        0, &arg_max_use           },
                 {}
         };
 
@@ -224,7 +224,7 @@ static int fix_permissions(
         return 0;
 }
 
-static int maybe_remove_external_coredump(const char *filename, off_t size) {
+static int maybe_remove_external_coredump(const char *filename, uint64_t size) {
 
         /* Returns 1 if might remove, 0 if will not remove, < 0 on error. */
 
@@ -285,7 +285,7 @@ static int save_external_coredump(
                 uid_t uid,
                 char **ret_filename,
                 int *ret_fd,
-                off_t *ret_size) {
+                uint64_t *ret_size) {
 
         _cleanup_free_ char *fn = NULL, *tmp = NULL;
         _cleanup_close_ int fd = -1;
@@ -372,9 +372,9 @@ static int save_external_coredump(
                 /* OK, this worked, we can get rid of the uncompressed version now */
                 unlink_noerrno(tmp);
 
-                *ret_filename = fn_compressed;    /* compressed */
-                *ret_fd = fd;                     /* uncompressed */
-                *ret_size = st.st_size;           /* uncompressed */
+                *ret_filename = fn_compressed;     /* compressed */
+                *ret_fd = fd;                      /* uncompressed */
+                *ret_size = (uint64_t) st.st_size; /* uncompressed */
 
                 fn_compressed = NULL;
                 fd = -1;
@@ -393,7 +393,7 @@ uncompressed:
 
         *ret_filename = fn;
         *ret_fd = fd;
-        *ret_size = st.st_size;
+        *ret_size = (uint64_t) st.st_size;
 
         fn = NULL;
         fd = -1;
@@ -544,7 +544,7 @@ int main(int argc, char* argv[]) {
         _cleanup_close_ int coredump_fd = -1;
 
         struct iovec iovec[26];
-        off_t coredump_size;
+        uint64_t coredump_size;
         int r, j = 0;
         uid_t uid, owner_uid;
         gid_t gid;
@@ -840,7 +840,7 @@ log:
 
         /* Optionally store the entire coredump in the journal */
         if (IN_SET(arg_storage, COREDUMP_STORAGE_JOURNAL, COREDUMP_STORAGE_BOTH) &&
-            coredump_size <= (off_t) arg_journal_size_max) {
+            coredump_size <= arg_journal_size_max) {
                 size_t sz = 0;
 
                 /* Store the coredump itself in the journal */
index 4f94799ce74708dbbb6b7536f19336043f1154f4..73d3a4bb9d2307f27a6484551fcb420b24c58f4b 100644 (file)
@@ -2542,7 +2542,7 @@ void journal_file_print_header(JournalFile *f) {
                        le64toh(f->header->n_entry_arrays));
 
         if (fstat(f->fd, &st) >= 0)
-                printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (off_t) st.st_blocks * 512ULL));
+                printf("Disk usage: %s\n", format_bytes(bytes, sizeof(bytes), (uint64_t) st.st_blocks * 512ULL));
 }
 
 static int journal_file_warn_btrfs(JournalFile *f) {
index 576e4e4d0354c7a2e3709da9c488838332bd216a..9b483413e778fb4489842dc9ca725143bd0f7a6f 100644 (file)
@@ -107,7 +107,7 @@ static bool arg_reverse = false;
 static int arg_journal_type = 0;
 static const char *arg_root = NULL;
 static const char *arg_machine = NULL;
-static off_t arg_vacuum_size = (off_t) -1;
+static uint64_t arg_vacuum_size = (uint64_t) -1;
 static usec_t arg_vacuum_time = USEC_INFINITY;
 
 static enum {
index 74554c1c342f1472a448b28bd8e5ca23a90994b9..bf7c773009ca974a3cebc50012bb479ede328132 100644 (file)
@@ -21,12 +21,12 @@ Journal.Seal,               config_parse_bool,       0, offsetof(Server, seal)
 Journal.SyncIntervalSec,    config_parse_sec,        0, offsetof(Server, sync_interval_usec)
 Journal.RateLimitInterval,  config_parse_sec,        0, offsetof(Server, rate_limit_interval)
 Journal.RateLimitBurst,     config_parse_unsigned,   0, offsetof(Server, rate_limit_burst)
-Journal.SystemMaxUse,       config_parse_iec_off,    0, offsetof(Server, system_metrics.max_use)
-Journal.SystemMaxFileSize,  config_parse_iec_off,    0, offsetof(Server, system_metrics.max_size)
-Journal.SystemKeepFree,     config_parse_iec_off,    0, offsetof(Server, system_metrics.keep_free)
-Journal.RuntimeMaxUse,      config_parse_iec_off,    0, offsetof(Server, runtime_metrics.max_use)
-Journal.RuntimeMaxFileSize, config_parse_iec_off,    0, offsetof(Server, runtime_metrics.max_size)
-Journal.RuntimeKeepFree,    config_parse_iec_off,    0, offsetof(Server, runtime_metrics.keep_free)
+Journal.SystemMaxUse,       config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_use)
+Journal.SystemMaxFileSize,  config_parse_iec_uint64, 0, offsetof(Server, system_metrics.max_size)
+Journal.SystemKeepFree,     config_parse_iec_uint64, 0, offsetof(Server, system_metrics.keep_free)
+Journal.RuntimeMaxUse,      config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.max_use)
+Journal.RuntimeMaxFileSize, config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.max_size)
+Journal.RuntimeKeepFree,    config_parse_iec_uint64, 0, offsetof(Server, runtime_metrics.keep_free)
 Journal.MaxRetentionSec,    config_parse_sec,        0, offsetof(Server, max_retention_usec)
 Journal.MaxFileSec,         config_parse_sec,        0, offsetof(Server, max_file_usec)
 Journal.ForwardToSyslog,    config_parse_bool,       0, offsetof(Server, forward_to_syslog)
index 41a566d7144d44f5514080881749e7f135682857..f17c00e60dc36a08bad306ec14761725b6a0390f 100644 (file)
@@ -44,8 +44,8 @@ typedef int (decompress_sw_t)(const void *src, uint64_t src_size,
                               const void *prefix, size_t prefix_len,
                               uint8_t extra);
 
-typedef int (compress_stream_t)(int fdf, int fdt, off_t max_bytes);
-typedef int (decompress_stream_t)(int fdf, int fdt, off_t max_size);
+typedef int (compress_stream_t)(int fdf, int fdt, uint64_t max_bytes);
+typedef int (decompress_stream_t)(int fdf, int fdt, uint64_t max_size);
 
 static void test_compress_decompress(int compression,
                                      compress_blob_t compress,
index a4dd00125d20f532b4542c65e7984fd644941a1e..514dadc1dc2a980f3009bdf5a18903c7f5276e8c 100644 (file)
@@ -25,7 +25,7 @@
 
 int main(int argc, char *argv[]) {
 
-        if (coredump_vacuum(-1, (off_t) -1, 70 * 1024) < 0)
+        if (coredump_vacuum(-1, (uint64_t) -1, 70 * 1024) < 0)
                 return EXIT_FAILURE;
 
         return EXIT_SUCCESS;
index 6826e2166545afc59e1977e686ade02b27d845aa..3e8cb0b7d0ded0cb1a5603f92860079a07ec01ac 100644 (file)
@@ -109,8 +109,7 @@ _public_ sd_bus_creds *sd_bus_creds_unref(sd_bus_creds *c) {
 
                         c->supplementary_gids = mfree(c->supplementary_gids);
 
-                        strv_free(c->well_known_names);
-                        c->well_known_names = NULL;
+                        c->well_known_names = strv_free(c->well_known_names);
 
                         bus_creds_done(c);
 
index a1f0f30d6cdc39284e5ec44e208af9bb46424b95..9a6d338231c7b2408fef0996e823db0606587acf 100644 (file)
@@ -1823,20 +1823,20 @@ static int parse_argv(int argc, char *argv[]) {
                         break;
 
                 case ARG_SIZE: {
-                        off_t o;
+                        uint64_t sz;
 
-                        r = parse_size(optarg, 1024, &o);
+                        r = parse_size(optarg, 1024, &sz);
                         if (r < 0) {
                                 log_error("Failed to parse size: %s", optarg);
                                 return r;
                         }
 
-                        if ((off_t) (size_t) o !=  o) {
+                        if ((uint64_t) (size_t) sz !=  sz) {
                                 log_error("Size out of range.");
                                 return -E2BIG;
                         }
 
-                        arg_snaplen = (size_t) o;
+                        arg_snaplen = (size_t) sz;
                         break;
                 }
 
index f2c89e365336f107b0106fc5986d46d3310952b1..47669afdef75ff8e9edd98700217769693f13971 100644 (file)
@@ -879,15 +879,15 @@ int config_parse_tmpfs_size(
 
                 *sz = PAGE_ALIGN((size_t) ((physical_memory() * (uint64_t) ul) / (uint64_t) 100));
         } else {
-                off_t o;
+                uint64_t k;
 
-                r = parse_size(rvalue, 1024, &o);
-                if (r < 0 || (off_t) (size_t) o != o) {
-                        log_syntax(unit, LOG_ERR, filename, line, r < 0 ? -r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
+                r = parse_size(rvalue, 1024, &k);
+                if (r < 0 || (uint64_t) (size_t) k != k) {
+                        log_syntax(unit, LOG_ERR, filename, line, r < 0 ? r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
                         return 0;
                 }
 
-                *sz = PAGE_ALIGN((size_t) o);
+                *sz = PAGE_ALIGN((size_t) k);
         }
 
         return 0;
index cc3811670455d1bcdcec480559d3963d16b1c109..6aaaa8aa31e990f9b23559fa674b9392e0488f70 100644 (file)
@@ -423,7 +423,7 @@ int bus_machine_method_get_os_release(sd_bus_message *message, void *userdata, s
                                         _exit(EXIT_FAILURE);
                         }
 
-                        r = copy_bytes(fd, pair[1], (off_t) -1, false);
+                        r = copy_bytes(fd, pair[1], (uint64_t) -1, false);
                         if (r < 0)
                                 _exit(EXIT_FAILURE);
 
index 7b8f6d1fabe3deaad7a9fe08c96124967744180d..ab113efb2872b2eb91d7d1885e5b6ca1eba240cf 100644 (file)
@@ -2385,13 +2385,9 @@ static int set_limit(int argc, char *argv[], void *userdata) {
         if (streq(argv[argc-1], "-"))
                 limit = (uint64_t) -1;
         else {
-                off_t off;
-
-                r = parse_size(argv[argc-1], 1024, &off);
+                r = parse_size(argv[argc-1], 1024, &limit);
                 if (r < 0)
                         return log_error("Failed to parse size: %s", argv[argc-1]);
-
-                limit = (uint64_t) off;
         }
 
         if (argc > 2)
index 33943a4b2f0b0847505c56ed23277f707130450a..5702df8ab47c6716ae83afb461803038eec91f3d 100644 (file)
@@ -3601,7 +3601,7 @@ finish:
 
         /* Try to flush whatever is still queued in the pty */
         if (master >= 0)
-                (void) copy_bytes(master, STDOUT_FILENO, (off_t) -1, false);
+                (void) copy_bytes(master, STDOUT_FILENO, (uint64_t) -1, false);
 
         loop_remove(loop_nr, &image_fd);
 
index 674bb6af281a136635cfbd5f7974bb78bfc5f615..8a59bd1c3ceb056a62a577d67e32092bd1a55f74 100644 (file)
@@ -90,11 +90,8 @@ void dns_zone_flush(DnsZone *z) {
         assert(hashmap_size(z->by_key) == 0);
         assert(hashmap_size(z->by_name) == 0);
 
-        hashmap_free(z->by_key);
-        z->by_key = NULL;
-
-        hashmap_free(z->by_name);
-        z->by_name = NULL;
+        z->by_key = hashmap_free(z->by_key);
+        z->by_name = hashmap_free(z->by_name);
 }
 
 static DnsZoneItem* dns_zone_get(DnsZone *z, DnsResourceRecord *rr) {
index 47f461a37d2ff2b31c82ca58cc5d5d69f4547b78..b9fd8e3dbcdba47f8d89365358398e652c1b4447 100644 (file)
@@ -238,8 +238,7 @@ static int link_update_domains(Link *l) {
         if (!l->unicast_scope)
                 return 0;
 
-        strv_free(l->unicast_scope->domains);
-        l->unicast_scope->domains = NULL;
+        l->unicast_scope->domains = strv_free(l->unicast_scope->domains);
 
         r = sd_network_link_get_domains(l->ifindex,
                                         &l->unicast_scope->domains);
index 36c44227c5fe9cb6fe81f64bf70864597e0c5907..4dc4ca581d35a5247d902760e5e1a526b9ff98b7 100644 (file)
@@ -1421,7 +1421,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 return bus_log_create_error(r);
 
         if (STR_IN_SET(field,
-                       "CPUAccounting", "MemoryAccounting", "BlockIOAccounting",
+                       "CPUAccounting", "MemoryAccounting", "BlockIOAccounting", "TasksAccounting",
                        "SendSIGHUP", "SendSIGKILL", "WakeSystem", "DefaultDependencies",
                        "IgnoreSIGPIPE", "TTYVHangup", "TTYReset", "RemainAfterExit")) {
 
@@ -1434,15 +1434,34 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                 r = sd_bus_message_append(m, "v", "b", r);
 
         } else if (streq(field, "MemoryLimit")) {
-                off_t bytes;
+                uint64_t bytes;
 
-                r = parse_size(eq, 1024, &bytes);
-                if (r < 0) {
-                        log_error("Failed to parse bytes specification %s", assignment);
-                        return -EINVAL;
+                if (isempty(eq) || streq(eq, "infinity"))
+                        bytes = (uint64_t) -1;
+                else {
+                        r = parse_size(eq, 1024, &bytes);
+                        if (r < 0) {
+                                log_error("Failed to parse bytes specification %s", assignment);
+                                return -EINVAL;
+                        }
+                }
+
+                r = sd_bus_message_append(m, "v", "t", bytes);
+
+        } else if (streq(field, "TasksMax")) {
+                uint64_t n;
+
+                if (isempty(eq) || streq(eq, "infinity"))
+                        n = (uint64_t) -1;
+                else {
+                        r = safe_atou64(eq, &n);
+                        if (r < 0) {
+                                log_error("Failed to parse maximum tasks specification %s", assignment);
+                                return -EINVAL;
+                        }
                 }
 
-                r = sd_bus_message_append(m, "v", "t", (uint64_t) bytes);
+                r = sd_bus_message_append(m, "v", "t", n);
 
         } else if (STR_IN_SET(field, "CPUShares", "BlockIOWeight")) {
                 uint64_t u;
@@ -1492,7 +1511,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                         r = sd_bus_message_append(m, "v", "a(st)", 0);
                 else {
                         const char *path, *bandwidth, *e;
-                        off_t bytes;
+                        uint64_t bytes;
 
                         e = strchr(eq, ' ');
                         if (e) {
@@ -1514,7 +1533,7 @@ int bus_append_unit_property_assignment(sd_bus_message *m, const char *assignmen
                                 return -EINVAL;
                         }
 
-                        r = sd_bus_message_append(m, "v", "a(st)", 1, path, (uint64_t) bytes);
+                        r = sd_bus_message_append(m, "v", "a(st)", 1, path, bytes);
                 }
 
         } else if (streq(field, "BlockIODeviceWeight")) {
index 23512f0d354153c5310c9650a549f9f7664f09df..946eac6823fd99e45e310229fedb41a0bd0f922a 100644 (file)
@@ -469,7 +469,7 @@ int config_parse_iec_size(const char* unit,
                             void *userdata) {
 
         size_t *sz = data;
-        off_t o;
+        uint64_t v;
         int r;
 
         assert(filename);
@@ -477,13 +477,13 @@ int config_parse_iec_size(const char* unit,
         assert(rvalue);
         assert(data);
 
-        r = parse_size(rvalue, 1024, &o);
-        if (r < 0 || (off_t) (size_t) o != o) {
-                log_syntax(unit, LOG_ERR, filename, line, r < 0 ? -r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
+        r = parse_size(rvalue, 1024, &v);
+        if (r < 0 || (uint64_t) (size_t) v != v) {
+                log_syntax(unit, LOG_ERR, filename, line, r < 0 ? r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
                 return 0;
         }
 
-        *sz = (size_t) o;
+        *sz = (size_t) v;
         return 0;
 }
 
@@ -499,7 +499,7 @@ int config_parse_si_size(const char* unit,
                             void *userdata) {
 
         size_t *sz = data;
-        off_t o;
+        uint64_t v;
         int r;
 
         assert(filename);
@@ -507,17 +507,17 @@ int config_parse_si_size(const char* unit,
         assert(rvalue);
         assert(data);
 
-        r = parse_size(rvalue, 1000, &o);
-        if (r < 0 || (off_t) (size_t) o != o) {
-                log_syntax(unit, LOG_ERR, filename, line, r < 0 ? -r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
+        r = parse_size(rvalue, 1000, &v);
+        if (r < 0 || (uint64_t) (size_t) v != v) {
+                log_syntax(unit, LOG_ERR, filename, line, r < 0 ? r : ERANGE, "Failed to parse size value, ignoring: %s", rvalue);
                 return 0;
         }
 
-        *sz = (size_t) o;
+        *sz = (size_t) v;
         return 0;
 }
 
-int config_parse_iec_off(const char* unit,
+int config_parse_iec_uint64(const char* unit,
                            const char *filename,
                            unsigned line,
                            const char *section,
@@ -528,7 +528,7 @@ int config_parse_iec_off(const char* unit,
                            void *data,
                            void *userdata) {
 
-        off_t *bytes = data;
+        uint64_t *bytes = data;
         int r;
 
         assert(filename);
@@ -536,11 +536,9 @@ int config_parse_iec_off(const char* unit,
         assert(rvalue);
         assert(data);
 
-        assert_cc(sizeof(off_t) == sizeof(uint64_t));
-
         r = parse_size(rvalue, 1024, bytes);
         if (r < 0)
-                log_syntax(unit, LOG_ERR, filename, line, -r, "Failed to parse size value, ignoring: %s", rvalue);
+                log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue);
 
         return 0;
 }
index 34e3815782d0786d8d15e88562ca1de9e1ea0fe1..4efed138c9f69a11d96d3611f89c5965a4eb83b4 100644 (file)
@@ -109,7 +109,7 @@ int config_parse_uint64(const char *unit, const char *filename, unsigned line, c
 int config_parse_double(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);
 int config_parse_iec_size(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);
 int config_parse_si_size(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);
-int config_parse_iec_off(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);
+int config_parse_iec_uint64(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);
 int config_parse_bool(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);
 int config_parse_tristate(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);
 int config_parse_string(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);
index 70220bdd14ada0d621b5e89ad2e2fe6273458002..9c1e4d5e13e261424d0a65f4275184645e3fd896 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <sys/statfs.h>
-#include <linux/fs.h>
 #include <fcntl.h>
+#include <linux/fs.h>
+#include <sys/statfs.h>
 
-#include "utf8.h"
 #include "btrfs-util.h"
-#include "path-util.h"
 #include "copy.h"
 #include "mkdir.h"
+#include "path-util.h"
 #include "rm-rf.h"
+#include "strv.h"
+#include "utf8.h"
+
 #include "machine-image.h"
 
 static const char image_search_path[] =
@@ -47,6 +49,38 @@ Image *image_unref(Image *i) {
         return NULL;
 }
 
+static char **image_settings_path(Image *image) {
+        _cleanup_strv_free_ char **l = NULL;
+        char **ret;
+        const char *fn, *s;
+        unsigned i = 0;
+
+        assert(image);
+
+        l = new0(char*, 4);
+        if (!l)
+                return NULL;
+
+        fn = strjoina(image->name, ".nspawn");
+
+        FOREACH_STRING(s, "/etc/systemd/nspawn/", "/run/systemd/nspawn/") {
+                l[i] = strappend(s, fn);
+                if (!l[i])
+                        return NULL;
+
+                i++;
+        }
+
+        l[i] = file_in_same_dir(image->path, fn);
+        if (!l[i])
+                return NULL;
+
+        ret = l;
+        l = NULL;
+
+        return ret;
+}
+
 static int image_new(
                 ImageType t,
                 const char *pretty,
@@ -341,6 +375,8 @@ void image_hashmap_free(Hashmap *map) {
 
 int image_remove(Image *i) {
         _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
+        _cleanup_strv_free_ char **settings = NULL;
+        char **j;
         int r;
 
         assert(i);
@@ -349,6 +385,10 @@ int image_remove(Image *i) {
             path_startswith(i->path, "/usr"))
                 return -EROFS;
 
+        settings = image_settings_path(i);
+        if (!settings)
+                return -ENOMEM;
+
         /* Make sure we don't interfere with a running nspawn */
         r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
         if (r < 0)
@@ -357,28 +397,56 @@ int image_remove(Image *i) {
         switch (i->type) {
 
         case IMAGE_SUBVOLUME:
-                return btrfs_subvol_remove(i->path, true);
+                r = btrfs_subvol_remove(i->path, true);
+                if (r < 0)
+                        return r;
+                break;
 
         case IMAGE_DIRECTORY:
                 /* Allow deletion of read-only directories */
                 (void) chattr_path(i->path, false, FS_IMMUTABLE_FL);
-                return rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
+                r = rm_rf(i->path, REMOVE_ROOT|REMOVE_PHYSICAL|REMOVE_SUBVOLUME);
+                if (r < 0)
+                        return r;
+
+                break;
 
         case IMAGE_RAW:
                 if (unlink(i->path) < 0)
                         return -errno;
-
-                return 0;
+                break;
 
         default:
                 return -EOPNOTSUPP;
         }
+
+        STRV_FOREACH(j, settings) {
+                if (unlink(*j) < 0 && errno != ENOENT)
+                        log_debug_errno(errno, "Failed to unlink %s, ignoring: %m", *j);
+        }
+
+        return 0;
+}
+
+static int rename_settings_file(const char *path, const char *new_name) {
+        _cleanup_free_ char *rs = NULL;
+        const char *fn;
+
+        fn = strjoina(new_name, ".nspawn");
+
+        rs = file_in_same_dir(path, fn);
+        if (!rs)
+                return -ENOMEM;
+
+        return rename_noreplace(AT_FDCWD, path, AT_FDCWD, rs);
 }
 
 int image_rename(Image *i, const char *new_name) {
         _cleanup_release_lock_file_ LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT, name_lock = LOCK_FILE_INIT;
         _cleanup_free_ char *new_path = NULL, *nn = NULL;
+        _cleanup_strv_free_ char **settings = NULL;
         unsigned file_attr = 0;
+        char **j;
         int r;
 
         assert(i);
@@ -390,6 +458,10 @@ int image_rename(Image *i, const char *new_name) {
             path_startswith(i->path, "/usr"))
                 return -EROFS;
 
+        settings = image_settings_path(i);
+        if (!settings)
+                return -ENOMEM;
+
         /* Make sure we don't interfere with a running nspawn */
         r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
         if (r < 0)
@@ -458,12 +530,33 @@ int image_rename(Image *i, const char *new_name) {
         i->name = nn;
         nn = NULL;
 
+        STRV_FOREACH(j, settings) {
+                r = rename_settings_file(*j, new_name);
+                if (r < 0 && r != -ENOENT)
+                        log_debug_errno(r, "Failed to rename settings file %s, ignoring: %m", *j);
+        }
+
         return 0;
 }
 
+static int clone_settings_file(const char *path, const char *new_name) {
+        _cleanup_free_ char *rs = NULL;
+        const char *fn;
+
+        fn = strjoina(new_name, ".nspawn");
+
+        rs = file_in_same_dir(path, fn);
+        if (!rs)
+                return -ENOMEM;
+
+        return copy_file_atomic(path, rs, 0664, false, 0);
+}
+
 int image_clone(Image *i, const char *new_name, bool read_only) {
         _cleanup_release_lock_file_ LockFile name_lock = LOCK_FILE_INIT;
+        _cleanup_strv_free_ char **settings = NULL;
         const char *new_path;
+        char **j;
         int r;
 
         assert(i);
@@ -471,6 +564,10 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
         if (!image_name_is_valid(new_name))
                 return -EINVAL;
 
+        settings = image_settings_path(i);
+        if (!settings)
+                return -ENOMEM;
+
         /* Make sure nobody takes the new name, between the time we
          * checked it is currently unused in all search paths, and the
          * time we take possesion of it */
@@ -506,6 +603,12 @@ int image_clone(Image *i, const char *new_name, bool read_only) {
         if (r < 0)
                 return r;
 
+        STRV_FOREACH(j, settings) {
+                r = clone_settings_file(*j, new_name);
+                if (r < 0 && r != -ENOENT)
+                        log_debug_errno(r, "Failed to clone settings %s, ignoring: %m", *j);
+        }
+
         return 0;
 }
 
index 479a9d5e8dc56fd51db3667c8c36782c3232f53a..41da820938bed34b7c1d417a6fc4ca1563b86694 100644 (file)
@@ -38,7 +38,7 @@ static pid_t pager_pid = 0;
 noreturn static void pager_fallback(void) {
         int r;
 
-        r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, (off_t) -1, false);
+        r = copy_bytes(STDIN_FILENO, STDOUT_FILENO, (uint64_t) -1, false);
         if (r < 0) {
                 log_error_errno(r, "Internal pager failed: %m");
                 _exit(EXIT_FAILURE);
index f6a127174ca61a408c572738825d4878fde58db0..d803bbe07e1cc68151218c4902e25ef1375edd3d 100644 (file)
@@ -333,8 +333,7 @@ int lookup_paths_init(
                 log_debug("Looking for unit files in (higher priority first):\n\t%s", t);
         } else {
                 log_debug("Ignoring unit files.");
-                strv_free(p->unit_path);
-                p->unit_path = NULL;
+                p->unit_path = strv_free(p->unit_path);
         }
 
         if (running_as == MANAGER_SYSTEM) {
@@ -390,8 +389,7 @@ int lookup_paths_init(
                         log_debug("Looking for SysV init scripts in:\n\t%s", t);
                 } else {
                         log_debug("Ignoring SysV init scripts.");
-                        strv_free(p->sysvinit_path);
-                        p->sysvinit_path = NULL;
+                        p->sysvinit_path = strv_free(p->sysvinit_path);
                 }
 
                 if (!strv_isempty(p->sysvrcnd_path)) {
@@ -403,8 +401,7 @@ int lookup_paths_init(
                         log_debug("Looking for SysV rcN.d links in:\n\t%s", t);
                 } else {
                         log_debug("Ignoring SysV rcN.d links.");
-                        strv_free(p->sysvrcnd_path);
-                        p->sysvrcnd_path = NULL;
+                        p->sysvrcnd_path = strv_free(p->sysvrcnd_path);
                 }
 #else
                 log_debug("SysV init scripts and rcN.d links support disabled");
@@ -417,8 +414,7 @@ int lookup_paths_init(
 void lookup_paths_free(LookupPaths *p) {
         assert(p);
 
-        strv_free(p->unit_path);
-        p->unit_path = NULL;
+        p->unit_path = strv_free(p->unit_path);
 
 #ifdef HAVE_SYSV_COMPAT
         strv_free(p->sysvinit_path);
index 20ded4dc0aef04d87807e7a4cd6ae0eca2aa5027..d21ba9a56665444f1ab7d5cd4122e7c8a1ec4c42 100644 (file)
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
-#include <sys/reboot.h>
-#include <linux/reboot.h>
-#include <stdio.h>
+#include <errno.h>
+#include <fcntl.h>
 #include <getopt.h>
+#include <linux/reboot.h>
 #include <locale.h>
 #include <stdbool.h>
+#include <stddef.h>
+#include <stdio.h>
 #include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <fcntl.h>
+#include <sys/reboot.h>
 #include <sys/socket.h>
-#include <stddef.h>
+#include <unistd.h>
 
+#include "sd-bus.h"
 #include "sd-daemon.h"
 #include "sd-login.h"
-#include "sd-bus.h"
-#include "log.h"
-#include "util.h"
-#include "macro.h"
-#include "set.h"
-#include "utmp-wtmp.h"
-#include "special.h"
-#include "initreq.h"
-#include "path-util.h"
-#include "strv.h"
+
+#include "build.h"
+#include "bus-common-errors.h"
+#include "bus-error.h"
+#include "bus-message.h"
+#include "bus-util.h"
 #include "cgroup-show.h"
 #include "cgroup-util.h"
-#include "list.h"
-#include "path-lookup.h"
-#include "exit-status.h"
-#include "build.h"
-#include "unit-name.h"
-#include "pager.h"
-#include "spawn-ask-password-agent.h"
-#include "spawn-polkit-agent.h"
-#include "install.h"
-#include "logs-show.h"
-#include "socket-util.h"
-#include "fileio.h"
 #include "copy.h"
-#include "env-util.h"
-#include "bus-util.h"
-#include "bus-message.h"
-#include "bus-error.h"
-#include "bus-common-errors.h"
-#include "mkdir.h"
 #include "dropin.h"
 #include "efivars.h"
+#include "env-util.h"
+#include "exit-status.h"
+#include "fileio.h"
 #include "formats-util.h"
-#include "process-util.h"
-#include "terminal-util.h"
 #include "hostname-util.h"
+#include "initreq.h"
+#include "install.h"
+#include "list.h"
+#include "log.h"
+#include "logs-show.h"
+#include "macro.h"
+#include "mkdir.h"
+#include "pager.h"
+#include "path-lookup.h"
+#include "path-util.h"
+#include "process-util.h"
+#include "set.h"
 #include "signal-util.h"
+#include "socket-util.h"
+#include "spawn-ask-password-agent.h"
+#include "spawn-polkit-agent.h"
+#include "special.h"
+#include "strv.h"
+#include "terminal-util.h"
+#include "unit-name.h"
+#include "util.h"
+#include "utmp-wtmp.h"
 
 static char **arg_types = NULL;
 static char **arg_states = NULL;
@@ -1477,6 +1478,8 @@ static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, cha
                                        "BindsTo\0",
                 [DEPENDENCY_REVERSE] = "RequiredBy\0"
                                        "RequiredByOverridable\0"
+                                       "RequisiteOf\0"
+                                       "RequisiteOfOverridable\0"
                                        "WantedBy\0"
                                        "PartOf\0"
                                        "BoundBy\0",
@@ -3297,6 +3300,8 @@ typedef struct UnitStatusInfo {
         uint64_t memory_current;
         uint64_t memory_limit;
         uint64_t cpu_usage_nsec;
+        uint64_t tasks_current;
+        uint64_t tasks_max;
 
         LIST_HEAD(ExecStatusInfo, exec);
 } UnitStatusInfo;
@@ -3555,6 +3560,15 @@ static void print_status_info(
         if (i->status_errno > 0)
                 printf("    Error: %i (%s)\n", i->status_errno, strerror(i->status_errno));
 
+        if (i->tasks_current != (uint64_t) -1) {
+                printf("    Tasks: %" PRIu64, i->tasks_current);
+
+                if (i->tasks_max != (uint64_t) -1)
+                        printf(" (limit: %" PRIi64 ")\n", i->tasks_max);
+                else
+                        printf("\n");
+        }
+
         if (i->memory_current != (uint64_t) -1) {
                 char buf[FORMAT_BYTES_MAX];
 
@@ -3790,6 +3804,10 @@ static int status_property(const char *name, sd_bus_message *m, UnitStatusInfo *
                         i->memory_current = u;
                 else if (streq(name, "MemoryLimit"))
                         i->memory_limit = u;
+                else if (streq(name, "TasksCurrent"))
+                        i->tasks_current = u;
+                else if (streq(name, "TasksMax"))
+                        i->tasks_max = u;
                 else if (streq(name, "CPUUsageNSec"))
                         i->cpu_usage_nsec = u;
 
@@ -4266,6 +4284,8 @@ static int show_one(
                 .memory_current = (uint64_t) -1,
                 .memory_limit = (uint64_t) -1,
                 .cpu_usage_nsec = (uint64_t) -1,
+                .tasks_current = (uint64_t) -1,
+                .tasks_max = (uint64_t) -1,
         };
         ExecStatusInfo *p;
         int r;
@@ -4641,7 +4661,7 @@ static int cat_file(const char *filename, bool newline) {
                ansi_highlight_off());
         fflush(stdout);
 
-        return copy_bytes(fd, STDOUT_FILENO, (off_t) -1, false);
+        return copy_bytes(fd, STDOUT_FILENO, (uint64_t) -1, false);
 }
 
 static int cat(sd_bus *bus, char **args) {
index b5e09cad26d91e460baa80ee70644c55d17ad5b0..aaa33354f490ce0f0021cb8a98b4940f775b5c8d 100644 (file)
@@ -207,7 +207,7 @@ static int make_backup(const char *target, const char *x) {
         if (r < 0)
                 return r;
 
-        r = copy_bytes(src, fileno(dst), (off_t) -1, true);
+        r = copy_bytes(src, fileno(dst), (uint64_t) -1, true);
         if (r < 0)
                 goto fail;
 
index b73c958ec5755893e637fc1f1de0b4ec2bcdb2a2..a03a68bd43778353cdd52580b4813f9a536dfee3 100644 (file)
@@ -146,7 +146,7 @@ static void test_copy_bytes(void) {
 
         assert_se(pipe2(pipefd, O_CLOEXEC) == 0);
 
-        r = copy_bytes(infd, pipefd[1], (off_t) -1, false);
+        r = copy_bytes(infd, pipefd[1], (uint64_t) -1, false);
         assert_se(r == 0);
 
         r = read(pipefd[0], buf, sizeof(buf));
index 8ceb71f22a9fea63a7c6c712e1f7e6b0f30f8c3d..7935442dbb6966788a7543bfe6a445b419fad781 100644 (file)
@@ -893,7 +893,7 @@ static void test_protect_errno(void) {
 }
 
 static void test_parse_size(void) {
-        off_t bytes;
+        uint64_t bytes;
 
         assert_se(parse_size("111", 1024, &bytes) == 0);
         assert_se(bytes == 111);
@@ -960,12 +960,12 @@ static void test_parse_size(void) {
         assert_se(parse_size("-10B 20K", 1024, &bytes) == -ERANGE);
 }
 
-static void test_config_parse_iec_off(void) {
-        off_t offset = 0;
-        assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
+static void test_config_parse_iec_uint64(void) {
+        uint64_t offset = 0;
+        assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4M", &offset, NULL) == 0);
         assert_se(offset == 4 * 1024 * 1024);
 
-        assert_se(config_parse_iec_off(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
+        assert_se(config_parse_iec_uint64(NULL, "/this/file", 11, "Section", 22, "Size", 0, "4.5M", &offset, NULL) == 0);
 }
 
 static void test_strextend(void) {
@@ -2250,7 +2250,7 @@ int main(int argc, char *argv[]) {
         test_u64log2();
         test_protect_errno();
         test_parse_size();
-        test_config_parse_iec_off();
+        test_config_parse_iec_uint64();
         test_strextend();
         test_strrep();
         test_split_pair();
index e74b02687ff59d318e37f724d6698a6b7b3c0613..ef7b9b954178ee7092a9028fa7da911409c9f79f 100644 (file)
@@ -10,6 +10,9 @@
 L /etc/os-release - - - - ../usr/lib/os-release
 L /etc/localtime - - - - ../usr/share/zoneinfo/UTC
 L+ /etc/mtab - - - - ../proc/self/mounts
+m4_ifdef(`HAVE_SMACK_RUN_LABEL',
+t /etc/mtab - - - - security.SMACK64=_
+)m4_dnl
 m4_ifdef(`ENABLE_RESOLVED',
 L! /etc/resolv.conf - - - - ../run/systemd/resolve/resolv.conf
 )m4_dnl