[arch-general] [arch-dev-public] Migration to systemd

Tom Gundersen teg at jklm.no
Wed Aug 15 09:49:37 EDT 2012


On Aug 15, 2012 3:32 PM, "Felipe Contreras" <felipe.contreras at gmail.com>
wrote:
>
> On Wed, Aug 15, 2012 at 2:16 PM, Thomas Bächler <thomas at archlinux.org>
wrote:
> > Am 15.08.2012 14:01, schrieb Felipe Contreras:
> >> On Wed, Aug 15, 2012 at 1:55 PM, Thomas Bächler <thomas at archlinux.org>
wrote:
> >>> Am 15.08.2012 13:34, schrieb Felipe Contreras:
> >>>>>> 1./ Be a small simple binary
> >>>>>
> >>>>> The systemd main binary is not very large (larger than sysvinit's
> >>>>> /sbin/init, but not by much).
> >>>>
> >>>> But that binary alone is useless, and certainly not *simple*.
> >>>
> >>> /sbin/init from sysvinit alone is useless. What is your point?
> >>
> >> The rest are rather simple scripts (in the case of Arch Linux).
> >>
> >> And you are still ignoring the fact that systemd is anything but
> >> *simple*. How convenient to ignore that argument.
> >
> > What argument? You _claim_ that it isn't simple, but you do not give any
> > proof for that claim.
>
> It is general knowledge that scripting languages are generally simpler
> than compiling languages.
>
> But fine, compare a few lines of rc.sysinit:
>
> # mount the API filesystems
> # /proc, /sys, /run, /dev, /run/lock, /dev/pts, /dev/shm
> mountpoint -q /proc    || mount -t proc proc /proc -o nosuid,noexec,nodev
> mountpoint -q /sys     || mount -t sysfs sys /sys -o nosuid,noexec,nodev
> mountpoint -q /run     || mount -t tmpfs run /run -o
mode=0755,nosuid,nodev
> mountpoint -q /dev     || mount -t devtmpfs dev /dev -o mode=0755,nosuid
> mkdir -p /dev/{pts,shm}
> mountpoint -q /dev/pts || mount -t devpts devpts /dev/pts -o
> mode=0620,gid=5,nosuid,noexec
> mountpoint -q /dev/shm || mount -t tmpfs shm /dev/shm -o
mode=1777,nosuid,nodev
>
> To their equivalent in systemd:
>
> ---
> #include <unistd.h>
> #include <fcntl.h>
> #include <errno.h>
> #include <string.h>
> #include <sys/stat.h>
> #include <sys/wait.h>
> #include <mntent.h>
>
> #include "log.h"
> #include "util.h"
> #include "path-util.h"
> #include "set.h"
> #include "mount-setup.h"
> #include "exit-status.h"
>
> /* Goes through /etc/fstab and remounts all API file systems, applying
>  * options that are in /etc/fstab that systemd might not have
>  * respected */
>
> int main(int argc, char *argv[]) {
>         int ret = EXIT_FAILURE;
>         FILE *f = NULL;
>         struct mntent* me;
>         Hashmap *pids = NULL;
>
>         if (argc > 1) {
>                 log_error("This program takes no argument.");
>                 return EXIT_FAILURE;
>         }
>
>         log_set_target(LOG_TARGET_AUTO);
>         log_parse_environment();
>         log_open();
>
>         umask(0022);
>
>         f = setmntent("/etc/fstab", "r");
>         if (!f) {
>                 if (errno == ENOENT) {
>                         ret = EXIT_SUCCESS;
>                         goto finish;
>                 }
>
>                 log_error("Failed to open /etc/fstab: %m");
>                 goto finish;
>         }
>
>         pids = hashmap_new(trivial_hash_func, trivial_compare_func);
>         if (!pids) {
>                 log_error("Failed to allocate set");
>                 goto finish;
>         }
>
>         ret = EXIT_SUCCESS;
>
>         while ((me = getmntent(f))) {
>                 pid_t pid;
>                 int k;
>                 char *s;
>
>                 /* Remount the root fs, /usr and all API VFS */
>                 if (!mount_point_is_api(me->mnt_dir) &&
>                     !path_equal(me->mnt_dir, "/") &&
>                     !path_equal(me->mnt_dir, "/usr"))
>                         continue;
>
>                 log_debug("Remounting %s", me->mnt_dir);
>
>                 pid = fork();
>                 if (pid < 0) {
>                         log_error("Failed to fork: %m");
>                         ret = EXIT_FAILURE;
>                         continue;
>                 }
>
>                 if (pid == 0) {
>                         const char *arguments[5];
>                         /* Child */
>
>                         arguments[0] = "/bin/mount";
>                         arguments[1] = me->mnt_dir;
>                         arguments[2] = "-o";
>                         arguments[3] = "remount";
>                         arguments[4] = NULL;
>
>                         execv("/bin/mount", (char **) arguments);
>
>                         log_error("Failed to execute /bin/mount: %m");
>                         _exit(EXIT_FAILURE);
>                 }
>
>                 /* Parent */
>
>                 s = strdup(me->mnt_dir);
>                 if (!s) {
>                         log_oom();
>                         ret = EXIT_FAILURE;
>                         continue;
>                 }
>
>
>                 k = hashmap_put(pids, UINT_TO_PTR(pid), s);
>                 if (k < 0) {
>                         log_error("Failed to add PID to set: %s",
strerror(-k));
>                         ret = EXIT_FAILURE;
>                         continue;
>                 }
>         }
>
>         while (!hashmap_isempty(pids)) {
>                 siginfo_t si;
>                 char *s;
>
>                 zero(si);
>                 if (waitid(P_ALL, 0, &si, WEXITED) < 0) {
>
>                         if (errno == EINTR)
>                                 continue;
>
>                         log_error("waitid() failed: %m");
>                         ret = EXIT_FAILURE;
>                         break;
>                 }
>
>                 s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid));
>                 if (s) {
>                         if (!is_clean_exit(si.si_code, si.si_status,
NULL)) {
>                                 if (si.si_code == CLD_EXITED)
>                                         log_error("/bin/mount for %s
> exited with exit status %i.", s, si.si_status);
>                                 else
>                                         log_error("/bin/mount for %s
> terminated by signal %s.", s, signal_to_string(si.si_status));
>
>                                 ret = EXIT_FAILURE;
>                         }
>
>                         free(s);
>                 }
>         }
>
> finish:
>
>         if (pids)
>                 hashmap_free_free(pids);
>
>         if (f)
>                 endmntent(f);
>
>         return ret;
> }
> ---
>
> If you think the second one is simpler, then I don't you know what
> 'simple' means.
>
> >>>>>> 2./ Have no dependencies
> >>>>>
> >>>>> That is pure BS. If something has no dependencies, it has to do
> >>>>> everything in the binary itself. You either end up with no
features, or
> >>>>> potential for tons of bugs.
> >>>>>
> >>>>> Having NO dependencies also means you have to bypass the C library
and
> >>>>> implement everything from scratch - that is the worst idea ever.
> >>>>
> >>>> No need to overreact, the meaning is clear:
> >>>>
> >>>> 2. Have as few dependencies as possible, preferably dependencies that
> >>>> are used widely in most systems and that have few dependencies
> >>>> themselves, and are simple themselves
> >>>
> >>> Okay, where exactly does systemd violate that?
> >>
> >> d-bus, for starters.
> >
> > Dependencies that are
> > * used widely - check
>
> Not as widely as shell, and libc, and util-linux. Some Arch Linux
> users don't use D-Bus, in fact, and it's not by default added to
> rc.conf precisely for that reason.
>
> > * in most systems - check
>
> Less than the Arch Linux systems that use initscripts.
>
> > * have few dependencies themselves - check
>
> libx11 is a cheap dependency for you?

Please stop spreading misinformation. libx11 is not an (indirect)
dependency of systemd.

> > * are simple themselves - ahemm
>
> D-Bus is extremely complicated. It's more than 100k likes of code.
>
> > So, dbus almost qualifies. You said "for starters", what others are
there.
> >
> >>>>>> 3./ Be easy to follow, fix and lockdown, best fit being interpreted
> >>>>>> languages.
> >>>>>
> >>>>> So, init should be a small binary in an interpreted language? Am I
the
> >>>>> only one who notices you are contradicting yourself.
> >>>>
> >>>> No. The "services" (in systemd lingo) should be in an interpreted
> >>>> language: e.g. shell.
> >>>
> >>> Why should they be? As far as I understand, they're human-readable
text
> >>> files. One might say this is an "interpreted language".
> >>
> >> No, they are compiled binaries. The code is in C (not interpreted).
> >
> > Ah, you mean those. You do realize that we now used many of those tools
> > in our initscripts, and I don't see you complaining about that.
>
> That is dangerous, but not as dangerous as going full systemd.
>
> But anyway, I am merely explaining what #3 means IMO.
>
> > There's probably plenty of reasons why they are in C, I don't know them.
> > In any case, I don't see how making something in a scripting language is
> > simpler - in contrast, I always find that writing a small C program for
> > a task is easier and the result is more robust than a script.
>
> And I find completely the opposite to be the case. Scripts are easier
> to write, read, and debug.
>
> > I'll stop discussing with you now, as this will lead nowhere. The fact
> > remains that all you do is complain, instead of providing an
> > alternative. The decisions are being made by the people who actually
> > _maintain_ this stuff inside Arch.
>
> The alternative is simple: stay with initscripts *at least* until the
> problems with systemd are sorted out.
>
> I just subscribed to this list, and 80% of the traffic I'm seeing is
> problems with systemd. That should tell you something; systemd has
> problems.
>
> Cheers.
>
> --
> Felipe Contreras


More information about the arch-general mailing list