예제 #1
0
void link_allocate_scopes(Link *l) {
        int r;

        assert(l);

        if (link_relevant(l, AF_UNSPEC, false) &&
            l->dns_servers) {
                if (!l->unicast_scope) {
                        r = dns_scope_new(l->manager, &l->unicast_scope, l, DNS_PROTOCOL_DNS, AF_UNSPEC);
                        if (r < 0)
                                log_warning_errno(r, "Failed to allocate DNS scope: %m");
                }
        } else
                l->unicast_scope = dns_scope_free(l->unicast_scope);

        if (link_relevant(l, AF_INET, true) &&
            l->llmnr_support != RESOLVE_SUPPORT_NO &&
            l->manager->llmnr_support != RESOLVE_SUPPORT_NO) {
                if (!l->llmnr_ipv4_scope) {
                        r = dns_scope_new(l->manager, &l->llmnr_ipv4_scope, l, DNS_PROTOCOL_LLMNR, AF_INET);
                        if (r < 0)
                                log_warning_errno(r, "Failed to allocate LLMNR IPv4 scope: %m");
                }
        } else
                l->llmnr_ipv4_scope = dns_scope_free(l->llmnr_ipv4_scope);

        if (link_relevant(l, AF_INET6, true) &&
            l->llmnr_support != RESOLVE_SUPPORT_NO &&
            l->manager->llmnr_support != RESOLVE_SUPPORT_NO &&
            socket_ipv6_is_supported()) {
                if (!l->llmnr_ipv6_scope) {
                        r = dns_scope_new(l->manager, &l->llmnr_ipv6_scope, l, DNS_PROTOCOL_LLMNR, AF_INET6);
                        if (r < 0)
                                log_warning_errno(r, "Failed to allocate LLMNR IPv6 scope: %m");
                }
        } else
                l->llmnr_ipv6_scope = dns_scope_free(l->llmnr_ipv6_scope);

        if (link_relevant(l, AF_INET, true) &&
            l->mdns_support != RESOLVE_SUPPORT_NO &&
            l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
                if (!l->mdns_ipv4_scope) {
                        r = dns_scope_new(l->manager, &l->mdns_ipv4_scope, l, DNS_PROTOCOL_MDNS, AF_INET);
                        if (r < 0)
                                log_warning_errno(r, "Failed to allocate mDNS IPv4 scope: %m");
                }
        } else
                l->mdns_ipv4_scope = dns_scope_free(l->mdns_ipv4_scope);

        if (link_relevant(l, AF_INET6, true) &&
            l->mdns_support != RESOLVE_SUPPORT_NO &&
            l->manager->mdns_support != RESOLVE_SUPPORT_NO) {
                if (!l->mdns_ipv6_scope) {
                        r = dns_scope_new(l->manager, &l->mdns_ipv6_scope, l, DNS_PROTOCOL_MDNS, AF_INET6);
                        if (r < 0)
                                log_warning_errno(r, "Failed to allocate mDNS IPv6 scope: %m");
                }
        } else
                l->mdns_ipv6_scope = dns_scope_free(l->mdns_ipv6_scope);
}
예제 #2
0
파일: pull-raw.c 프로젝트: dankor/systemd
static int raw_pull_copy_auxiliary_file(
                RawPull *i,
                const char *suffix,
                char **path) {

        const char *local;
        int r;

        assert(i);
        assert(suffix);
        assert(path);

        r = raw_pull_determine_path(i, suffix, path);
        if (r < 0)
                return r;

        local = strjoina(i->image_root, "/", i->local, suffix);

        r = copy_file_atomic(*path, local, 0644, 0, COPY_REFLINK | (i->force_local ? COPY_REPLACE : 0));
        if (r == -EEXIST)
                log_warning_errno(r, "File %s already exists, not replacing.", local);
        else if (r == -ENOENT)
                log_debug_errno(r, "Skipping creation of auxiliary file, since none was found.");
        else if (r < 0)
                log_warning_errno(r, "Failed to copy file %s, ignoring: %m", local);
        else
                log_info("Created new file %s.", local);

        return 0;
}
예제 #3
0
int main(int argc, char *argv[]) {
        usec_t t;
        unsigned i, count;
        int r;
        bool slow;

        log_set_max_level(LOG_DEBUG);
        log_parse_environment();

        r = getenv_bool("SYSTEMD_SLOW_TESTS");
        slow = r >= 0 ? r : SYSTEMD_SLOW_TESTS_DEFAULT;

        t = slow ? 10 * USEC_PER_SEC : 1 * USEC_PER_SEC;
        count = slow ? 5 : 3;

        r = watchdog_set_timeout(&t);
        if (r < 0)
                log_warning_errno(r, "Failed to open watchdog: %m");
        if (r == -EPERM)
                t = 0;

        for (i = 0; i < count; i++) {
                log_info("Pinging...");
                r = watchdog_ping();
                if (r < 0)
                        log_warning_errno(r, "Failed to ping watchdog: %m");

                usleep(t/2);
        }

        watchdog_close(true);
        return 0;
}
예제 #4
0
static int clean_sysvipc_shm(uid_t delete_uid) {
        _cleanup_fclose_ FILE *f = NULL;
        char line[LINE_MAX];
        bool first = true;
        int ret = 0;

        f = fopen("/proc/sysvipc/shm", "re");
        if (!f) {
                if (errno == ENOENT)
                        return 0;

                log_warning_errno(errno, "Failed to open /proc/sysvipc/shm: %m");
                return -errno;
        }

        FOREACH_LINE(line, f, goto fail) {
                unsigned n_attached;
                pid_t cpid, lpid;
                uid_t uid, cuid;
                gid_t gid, cgid;
                int shmid;

                if (first) {
                        first = false;
                        continue;
                }

                truncate_nl(line);

                if (sscanf(line, "%*i %i %*o %*u " PID_FMT " " PID_FMT " %u " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
                           &shmid, &cpid, &lpid, &n_attached, &uid, &gid, &cuid, &cgid) != 8)
                        continue;

                if (n_attached > 0)
                        continue;

                if (uid != delete_uid)
                        continue;

                if (shmctl(shmid, IPC_RMID, NULL) < 0) {

                        /* Ignore entries that are already deleted */
                        if (errno == EIDRM || errno == EINVAL)
                                continue;

                        ret = log_warning_errno(errno,
                                                "Failed to remove SysV shared memory segment %i: %m",
                                                shmid);
                }
        }

        return ret;

fail:
        log_warning_errno(errno, "Failed to read /proc/sysvipc/shm: %m");
        return -errno;
}
예제 #5
0
int server_restore_streams(Server *s, FDSet *fds) {
        _cleanup_closedir_ DIR *d = NULL;
        struct dirent *de;
        int r;

        d = opendir("/run/systemd/journal/streams");
        if (!d) {
                if (errno == ENOENT)
                        return 0;

                return log_warning_errno(errno, "Failed to enumerate /run/systemd/journal/streams: %m");
        }

        FOREACH_DIRENT(de, d, goto fail) {
                unsigned long st_dev, st_ino;
                bool found = false;
                Iterator i;
                int fd;

                if (sscanf(de->d_name, "%lu:%lu", &st_dev, &st_ino) != 2)
                        continue;

                FDSET_FOREACH(fd, fds, i) {
                        struct stat st;

                        if (fstat(fd, &st) < 0)
                                return log_error_errno(errno, "Failed to stat %s: %m", de->d_name);

                        if (S_ISSOCK(st.st_mode) && st.st_dev == st_dev && st.st_ino == st_ino) {
                                found = true;
                                break;
                        }
                }

                if (!found) {
                        /* No file descriptor? Then let's delete the state file */
                        log_debug("Cannot restore stream file %s", de->d_name);
                        if (unlinkat(dirfd(d), de->d_name, 0) < 0)
                                log_warning_errno(errno, "Failed to remove /run/systemd/journal/streams/%s: %m",
                                                  de->d_name);
                        continue;
                }

                fdset_remove(fds, fd);

                r = stdout_stream_restore(s, de->d_name, fd);
                if (r < 0)
                        safe_close(fd);
        }

        return 0;

fail:
        return log_error_errno(errno, "Failed to read streams directory: %m");
}
예제 #6
0
static int clean_posix_mq(uid_t uid) {
        _cleanup_closedir_ DIR *dir = NULL;
        struct dirent *de;
        int ret = 0;

        dir = opendir("/dev/mqueue");
        if (!dir) {
                if (errno == ENOENT)
                        return 0;

                log_warning_errno(errno, "Failed to open /dev/mqueue: %m");
                return -errno;
        }

        FOREACH_DIRENT(de, dir, goto fail) {
                struct stat st;
                char fn[1+strlen(de->d_name)+1];

                if (STR_IN_SET(de->d_name, "..", "."))
                        continue;

                if (fstatat(dirfd(dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
                        if (errno == ENOENT)
                                continue;

                        ret = log_warning_errno(errno,
                                                "Failed to stat() MQ segment %s: %m",
                                                de->d_name);
                        continue;
                }

                if (st.st_uid != uid)
                        continue;

                fn[0] = '/';
                strcpy(fn+1, de->d_name);

                if (mq_unlink(fn) < 0) {
                        if (errno == ENOENT)
                                continue;

                        ret = log_warning_errno(errno,
                                                "Failed to unlink POSIX message queue %s: %m",
                                                fn);
                }
        }

        return ret;

fail:
        log_warning_errno(errno, "Failed to read /dev/mqueue: %m");
        return -errno;
}
예제 #7
0
static int clean_sysvipc_msg(uid_t delete_uid) {
        _cleanup_fclose_ FILE *f = NULL;
        char line[LINE_MAX];
        bool first = true;
        int ret = 0;

        f = fopen("/proc/sysvipc/msg", "re");
        if (!f) {
                if (errno == ENOENT)
                        return 0;

                log_warning_errno(errno, "Failed to open /proc/sysvipc/msg: %m");
                return -errno;
        }

        FOREACH_LINE(line, f, goto fail) {
                uid_t uid, cuid;
                gid_t gid, cgid;
                pid_t cpid, lpid;
                int msgid;

                if (first) {
                        first = false;
                        continue;
                }

                truncate_nl(line);

                if (sscanf(line, "%*i %i %*o %*u %*u " PID_FMT " " PID_FMT " " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
                           &msgid, &cpid, &lpid, &uid, &gid, &cuid, &cgid) != 7)
                        continue;

                if (uid != delete_uid)
                        continue;

                if (msgctl(msgid, IPC_RMID, NULL) < 0) {

                        /* Ignore entries that are already deleted */
                        if (errno == EIDRM || errno == EINVAL)
                                continue;

                        ret = log_warning_errno(errno,
                                                "Failed to remove SysV message queue %i: %m",
                                                msgid);
                }
        }

        return ret;

fail:
        log_warning_errno(errno, "Failed to read /proc/sysvipc/msg: %m");
        return -errno;
}
예제 #8
0
static int clean_sysvipc_sem(uid_t delete_uid) {
        _cleanup_fclose_ FILE *f = NULL;
        char line[LINE_MAX];
        bool first = true;
        int ret = 0;

        f = fopen("/proc/sysvipc/sem", "re");
        if (!f) {
                if (errno == ENOENT)
                        return 0;

                log_warning_errno(errno, "Failed to open /proc/sysvipc/sem: %m");
                return -errno;
        }

        FOREACH_LINE(line, f, goto fail) {
                uid_t uid, cuid;
                gid_t gid, cgid;
                int semid;

                if (first) {
                        first = false;
                        continue;
                }

                truncate_nl(line);

                if (sscanf(line, "%*i %i %*o %*u " UID_FMT " " GID_FMT " " UID_FMT " " GID_FMT,
                           &semid, &uid, &gid, &cuid, &cgid) != 5)
                        continue;

                if (uid != delete_uid)
                        continue;

                if (semctl(semid, 0, IPC_RMID) < 0) {

                        /* Ignore entries that are already deleted */
                        if (errno == EIDRM || errno == EINVAL)
                                continue;

                        ret = log_warning_errno(errno,
                                                "Failed to remove SysV semaphores object %i: %m",
                                                semid);
                }
        }

        return ret;

fail:
        log_warning_errno(errno, "Failed to read /proc/sysvipc/sem: %m");
        return -errno;
}
예제 #9
0
파일: watchdog.c 프로젝트: abbradar/systemd
void watchdog_close(bool disarm) {
        int r;

        if (watchdog_fd < 0)
                return;

        if (disarm) {
                int flags;

                /* Explicitly disarm it */
                flags = WDIOS_DISABLECARD;
                r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
                if (r < 0)
                        log_warning_errno(errno, "Failed to disable hardware watchdog: %m");

                /* To be sure, use magic close logic, too */
                for (;;) {
                        static const char v = 'V';

                        if (write(watchdog_fd, &v, 1) > 0)
                                break;

                        if (errno != EINTR) {
                                log_error_errno(errno, "Failed to disarm watchdog timer: %m");
                                break;
                        }
                }
        }

        watchdog_fd = safe_close(watchdog_fd);
}
예제 #10
0
int main(int argc, char *argv[]) {
        static const char* const sulogin_cmdline[] = {SULOGIN, NULL};
        _cleanup_(sd_bus_flush_close_unrefp) sd_bus *bus = NULL;
        int r;

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        print_mode(argc > 1 ? argv[1] : "");

        (void) fork_wait(sulogin_cmdline);

        r = bus_connect_system_systemd(&bus);
        if (r < 0) {
                log_warning_errno(r, "Failed to get D-Bus connection: %m");
                r = 0;
        } else {
                (void) reload_manager(bus);

                r = start_default_target(bus);
        }

        return r >= 0 ? EXIT_SUCCESS : EXIT_FAILURE;
}
예제 #11
0
static int unit_file_find_dir(
                const char *original_root,
                const char *path,
                char ***dirs) {

        _cleanup_free_ char *chased = NULL;
        int r;

        assert(path);

        r = chase_symlinks(path, original_root, 0, &chased);
        if (r == -ENOENT) /* Ignore -ENOENT, after all most units won't have a drop-in dir. */
                return 0;
        if (r == -ENAMETOOLONG) {
                /* Also, ignore -ENAMETOOLONG but log about it. After all, users are not even able to create the
                 * drop-in dir in such case. This mostly happens for device units with an overly long /sys path. */
                log_debug_errno(r, "Path '%s' too long, couldn't canonicalize, ignoring.", path);
                return 0;
        }
        if (r < 0)
                return log_warning_errno(r, "Failed to canonicalize path '%s': %m", path);

        r = strv_push(dirs, chased);
        if (r < 0)
                return log_oom();

        chased = NULL;
        return 0;
}
int main(int argc, char *argv[]) {
        int r, k;

        if (argc > 1 && argc != 4) {
                log_error("This program takes three or no arguments.");
                return EXIT_FAILURE;
        }

        if (argc > 1)
                arg_dest = argv[2];

        log_set_target(LOG_TARGET_SAFE);
        log_parse_environment();
        log_open();

        umask(0022);

        r = generate_symlink();

        if (r > 0) {
                k = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
                if (k < 0)
                        log_warning_errno(k, "Failed to parse kernel command line, ignoring: %m");
        }

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #13
0
static void print_welcome(void) {
        _cleanup_free_ char *pretty_name = NULL;
        const char *os_release = NULL;
        static bool done = false;
        int r;

        if (done)
                return;

        os_release = prefix_roota(arg_root, "/etc/os-release");
        r = parse_env_file(os_release, NEWLINE,
                           "PRETTY_NAME", &pretty_name,
                           NULL);
        if (r == -ENOENT) {

                os_release = prefix_roota(arg_root, "/usr/lib/os-release");
                r = parse_env_file(os_release, NEWLINE,
                                   "PRETTY_NAME", &pretty_name,
                                   NULL);
        }

        if (r < 0 && r != -ENOENT)
                log_warning_errno(r, "Failed to read os-release file: %m");

        printf("\nWelcome to your new installation of %s!\nPlease configure a few basic system settings:\n\n",
               isempty(pretty_name) ? "Linux" : pretty_name);

        press_any_key();

        done = true;
}
예제 #14
0
파일: coredump.c 프로젝트: rothwerx/systemd
static int allocate_journal_field(int fd, size_t size, char **ret, size_t *ret_size) {
        _cleanup_free_ char *field = NULL;
        ssize_t n;

        assert(fd >= 0);
        assert(ret);
        assert(ret_size);

        if (lseek(fd, 0, SEEK_SET) == (off_t) -1)
                return log_warning_errno(errno, "Failed to seek: %m");

        field = malloc(9 + size);
        if (!field) {
                log_warning("Failed to allocate memory for coredump, coredump will not be stored.");
                return -ENOMEM;
        }

        memcpy(field, "COREDUMP=", 9);

        n = read(fd, field + 9, size);
        if (n < 0)
                return log_error_errno((int) n, "Failed to read core data: %m");
        if ((size_t) n < size) {
                log_error("Core data too short.");
                return -EIO;
        }

        *ret = field;
        *ret_size = size + 9;

        field = NULL;

        return 0;
}
예제 #15
0
int main(int argc, char *argv[]) {
        int r = 0;

        if (argc > 1 && argc != 4) {
                log_error("This program takes three or no arguments.");
                return EXIT_FAILURE;
        }

        if (argc > 1)
                arg_dest = argv[1];

        log_set_prohibit_ipc(true);
        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        /* Don't even consider resuming outside of initramfs. */
        if (!in_initrd())
                return EXIT_SUCCESS;

        r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
        if (r < 0)
                log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");

        r = process_resume();
        free(arg_resume_device);

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #16
0
파일: pull-raw.c 프로젝트: swem/systemd
static int raw_pull_job_on_open_disk_raw(PullJob *j) {
        RawPull *i;
        int r;

        assert(j);
        assert(j->userdata);

        i = j->userdata;
        assert(i->raw_job == j);
        assert(!i->final_path);
        assert(!i->temp_path);

        r = pull_make_path(j->url, j->etag, i->image_root, ".raw-", ".raw", &i->final_path);
        if (r < 0)
                return log_oom();

        r = tempfn_random(i->final_path, NULL, &i->temp_path);
        if (r < 0)
                return log_oom();

        (void) mkdir_parents_label(i->temp_path, 0700);

        j->disk_fd = open(i->temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
        if (j->disk_fd < 0)
                return log_error_errno(errno, "Failed to create %s: %m", i->temp_path);

        r = chattr_fd(j->disk_fd, FS_NOCOW_FL, FS_NOCOW_FL);
        if (r < 0)
                log_warning_errno(errno, "Failed to set file attributes on %s: %m", i->temp_path);

        return 0;
}
예제 #17
0
int button_open(Button *b) {
        char *p, name[256];
        int r;

        assert(b);

        b->fd = safe_close(b->fd);

        p = strjoina("/dev/input/", b->name);

        b->fd = open(p, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK);
        if (b->fd < 0)
                return log_warning_errno(errno, "Failed to open %s: %m", b->name);

        if (ioctl(b->fd, EVIOCGNAME(sizeof(name)), name) < 0) {
                r = log_error_errno(errno, "Failed to get input name: %m");
                goto fail;
        }

        r = sd_event_add_io(b->manager->event, &b->io_event_source, b->fd, EPOLLIN, button_dispatch, b);
        if (r < 0) {
                log_error_errno(r, "Failed to add button event: %m");
                goto fail;
        }

        log_info("Watching system buttons on /dev/input/%s (%s)", b->name, name);

        return 0;

fail:
        b->fd = safe_close(b->fd);
        return r;
}
예제 #18
0
static int write_requires_after(FILE *f, const char *opts) {
    _cleanup_strv_free_ char **names = NULL, **units = NULL;
    _cleanup_free_ char *res = NULL;
    char **s;
    int r;

    assert(f);
    assert(opts);

    r = fstab_extract_values(opts, "x-systemd.requires", &names);
    if (r < 0)
        return log_warning_errno(r, "Failed to parse options: %m");
    if (r == 0)
        return 0;

    STRV_FOREACH(s, names) {
        char *x;

        r = unit_name_mangle_with_suffix(*s, UNIT_NAME_NOGLOB, ".mount", &x);
        if (r < 0)
            return log_error_errno(r, "Failed to generate unit name: %m");
        r = strv_consume(&units, x);
        if (r < 0)
            return log_oom();
    }
예제 #19
0
파일: bootctl.c 프로젝트: Rydoo42/systemd
static void read_loader_efi_var(const char *name, char **var) {
        int r;

        r = efi_get_variable_string(EFI_VENDOR_LOADER, name, var);
        if (r < 0 && r != -ENOENT)
                log_warning_errno(r, "Failed to read EFI variable %s: %m", name);
}
예제 #20
0
static int accept_cb(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
        _cleanup_free_ char *peer = NULL;
        Context *context = userdata;
        int nfd = -1, r;

        assert(s);
        assert(fd >= 0);
        assert(revents & EPOLLIN);
        assert(context);

        nfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
        if (nfd < 0) {
                if (errno != -EAGAIN)
                        log_warning_errno(errno, "Failed to accept() socket: %m");
        } else {
                getpeername_pretty(nfd, true, &peer);
                log_debug("New connection from %s", strna(peer));

                r = add_connection_socket(context, nfd);
                if (r < 0) {
                        log_error_errno(r, "Failed to accept connection, ignoring: %m");
                        safe_close(fd);
                }
        }

        r = sd_event_source_set_enabled(s, SD_EVENT_ONESHOT);
        if (r < 0) {
                log_error_errno(r, "Error while re-enabling listener with ONESHOT: %m");
                sd_event_exit(context->event, r);
                return r;
        }

        return 1;
}
예제 #21
0
static int fifo_process(Fifo *f) {
        ssize_t l;

        assert(f);

        errno = EIO;
        l = read(f->fd,
                 ((uint8_t*) &f->buffer) + f->bytes_read,
                 sizeof(f->buffer) - f->bytes_read);
        if (l <= 0) {
                if (errno == EAGAIN)
                        return 0;

                return log_warning_errno(errno, "Failed to read from fifo: %m");
        }

        f->bytes_read += l;
        assert(f->bytes_read <= sizeof(f->buffer));

        if (f->bytes_read == sizeof(f->buffer)) {
                request_process(f->server, &f->buffer);
                f->bytes_read = 0;
        }

        return 0;
}
예제 #22
0
static int raw_import_open_disk(RawImport *i) {
        int r;

        assert(i);

        assert(!i->final_path);
        assert(!i->temp_path);
        assert(i->output_fd < 0);

        i->final_path = strjoin(i->image_root, "/", i->local, ".raw");
        if (!i->final_path)
                return log_oom();

        r = tempfn_random(i->final_path, NULL, &i->temp_path);
        if (r < 0)
                return log_oom();

        (void) mkdir_parents_label(i->temp_path, 0700);

        i->output_fd = open(i->temp_path, O_RDWR|O_CREAT|O_EXCL|O_NOCTTY|O_CLOEXEC, 0664);
        if (i->output_fd < 0)
                return log_error_errno(errno, "Failed to open destination %s: %m", i->temp_path);

        r = chattr_fd(i->output_fd, FS_NOCOW_FL, FS_NOCOW_FL);
        if (r < 0)
                log_warning_errno(r, "Failed to set file attributes on %s: %m", i->temp_path);

        return 0;
}
예제 #23
0
void server_process_native_message(
                Server *s,
                const void *buffer, size_t buffer_size,
                const struct ucred *ucred,
                const struct timeval *tv,
                const char *label, size_t label_len) {

        size_t remaining = buffer_size;
        ClientContext *context;
        int r;

        assert(s);
        assert(buffer || buffer_size == 0);

        if (ucred && pid_is_valid(ucred->pid)) {
                r = client_context_get(s, ucred->pid, ucred, label, label_len, NULL, &context);
                if (r < 0)
                        log_warning_errno(r, "Failed to retrieve credentials for PID " PID_FMT ", ignoring: %m", ucred->pid);
        }

        do {
                r = server_process_entry(s,
                                         (const uint8_t*) buffer + (buffer_size - remaining), &remaining,
                                         context, ucred, tv, label, label_len);
        } while (r == 0);
}
예제 #24
0
static size_t cache_max(void) {
        static size_t cached = -1;

        if (cached == (size_t) -1) {
                uint64_t mem_total;
                int r;

                r = procfs_memory_get(&mem_total, NULL);
                if (r < 0) {
                        log_warning_errno(r, "Cannot query /proc/meminfo for MemTotal: %m");
                        cached = CACHE_MAX_FALLBACK;
                } else {
                        /* Cache entries are usually a few kB, but the process cmdline is controlled by the
                         * user and can be up to _SC_ARG_MAX, usually 2MB. Let's say that approximately up to
                         * 1/8th of memory may be used by the cache.
                         *
                         * In the common case, this formula gives 64 cache entries for each GB of RAM.
                         */
                        long l = sysconf(_SC_ARG_MAX);
                        assert(l > 0);

                        cached = CLAMP(mem_total / 8 / (uint64_t) l, CACHE_MAX_MIN, CACHE_MAX_MAX);
                }
        }

        return cached;
}
예제 #25
0
int main(int argc, char *argv[]) {
        int r = 0;

        if (argc > 1 && argc != 4) {
                log_error("This program takes three or no arguments.");
                return EXIT_FAILURE;
        }

        if (argc > 1)
                arg_dest = argv[1];

        log_set_target(LOG_TARGET_SAFE);
        log_parse_environment();
        log_open();

        umask(0022);

        r = parse_proc_cmdline(parse_proc_cmdline_item);
        if (r < 0)
                log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");

        /* Always honour root= and usr= in the kernel command line if we are in an initrd */
        if (in_initrd()) {
                r = add_root_mount();
                if (r == 0)
                        r = add_usr_mount();
        }

        /* Honour /etc/fstab only when that's enabled */
        if (arg_fstab_enabled) {
                int k;

                log_debug("Parsing /etc/fstab");

                /* Parse the local /etc/fstab, possibly from the initrd */
                k = parse_fstab(false);
                if (k < 0)
                        r = k;

                /* If running in the initrd also parse the /etc/fstab from the host */
                if (in_initrd()) {
                        log_debug("Parsing /sysroot/etc/fstab");

                        k = parse_fstab(true);
                        if (k < 0)
                                r = k;
                }
        }

        free(arg_root_what);
        free(arg_root_fstype);
        free(arg_root_options);

        free(arg_usr_what);
        free(arg_usr_fstype);
        free(arg_usr_options);

        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #26
0
int manager_write_resolv_conf(Manager *m) {

        _cleanup_ordered_set_free_ OrderedSet *dns = NULL, *domains = NULL;
        _cleanup_free_ char *temp_path = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        int r;

        assert(m);

        /* Read the system /etc/resolv.conf first */
        (void) manager_read_resolv_conf(m);

        /* Add the full list to a set, to filter out duplicates */
        r = manager_compile_dns_servers(m, &dns);
        if (r < 0)
                return log_warning_errno(r, "Failed to compile list of DNS servers: %m");

        r = manager_compile_search_domains(m, &domains, false);
        if (r < 0)
                return log_warning_errno(r, "Failed to compile list of search domains: %m");

        r = fopen_temporary_label(PRIVATE_RESOLV_CONF, PRIVATE_RESOLV_CONF, &f, &temp_path);
        if (r < 0)
                return log_warning_errno(r, "Failed to open private resolv.conf file for writing: %m");

        (void) fchmod(fileno(f), 0644);

        r = write_resolv_conf_contents(f, dns, domains);
        if (r < 0) {
                log_error_errno(r, "Failed to write private resolv.conf contents: %m");
                goto fail;
        }

        if (rename(temp_path, PRIVATE_RESOLV_CONF) < 0) {
                r = log_error_errno(errno, "Failed to move private resolv.conf file into place: %m");
                goto fail;
        }

        return 0;

fail:
        (void) unlink(PRIVATE_RESOLV_CONF);
        (void) unlink(temp_path);

        return r;
}
예제 #27
0
파일: quotacheck.c 프로젝트: OpenDZ/systemd
int main(int argc, char *argv[]) {

        static const char * const cmdline[] = {
                QUOTACHECK,
                "-anug",
                NULL
        };

        pid_t pid;
        int r;

        if (argc > 1) {
                log_error("This program takes no arguments.");
                return EXIT_FAILURE;
        }

        log_set_target(LOG_TARGET_AUTO);
        log_parse_environment();
        log_open();

        umask(0022);

        r = proc_cmdline_parse(parse_proc_cmdline_item, NULL, 0);
        if (r < 0)
                log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m");

        test_files();

        if (!arg_force) {
                if (arg_skip)
                        return EXIT_SUCCESS;

                if (access("/run/systemd/quotacheck", F_OK) < 0)
                        return EXIT_SUCCESS;
        }

        pid = fork();
        if (pid < 0) {
                r = log_error_errno(errno, "fork(): %m");
                goto finish;
        }
        if (pid == 0) {

                /* Child */

                (void) reset_all_signal_handlers();
                (void) reset_signal_mask();
                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);

                execv(cmdline[0], (char**) cmdline);
                _exit(1); /* Operational error */
        }

        r = wait_for_terminate_and_warn("quotacheck", pid, true);

finish:
        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
예제 #28
0
파일: killall.c 프로젝트: AOSC-Dev/systemd
static int killall(int sig, Set *pids, bool send_sighup) {
        _cleanup_closedir_ DIR *dir = NULL;
        struct dirent *d;

        dir = opendir("/proc");
        if (!dir)
                return -errno;

        while ((d = readdir(dir))) {
                pid_t pid;
                int r;

                if (d->d_type != DT_DIR &&
                    d->d_type != DT_UNKNOWN)
                        continue;

                if (parse_pid(d->d_name, &pid) < 0)
                        continue;

                if (ignore_proc(pid, sig == SIGKILL && !in_initrd()))
                        continue;

                if (sig == SIGKILL) {
                        _cleanup_free_ char *s = NULL;

                        get_process_comm(pid, &s);
                        log_notice("Sending SIGKILL to PID "PID_FMT" (%s).", pid, strna(s));
                }

                if (kill(pid, sig) >= 0) {
                        if (pids) {
                                r = set_put(pids, PID_TO_PTR(pid));
                                if (r < 0)
                                        log_oom();
                        }
                } else if (errno != ENOENT)
                        log_warning_errno(errno, "Could not kill %d: %m", pid);

                if (send_sighup) {
                        /* Optionally, also send a SIGHUP signal, but
                        only if the process has a controlling
                        tty. This is useful to allow handling of
                        shells which ignore SIGTERM but react to
                        SIGHUP. We do not send this to processes that
                        have no controlling TTY since we don't want to
                        trigger reloads of daemon processes. Also we
                        make sure to only send this after SIGTERM so
                        that SIGTERM is always first in the queue. */


                        if (get_ctty_devnr(pid, NULL) >= 0)
                                kill(pid, SIGHUP);
                }
        }

        return set_size(pids);
}
예제 #29
0
파일: watchdog.c 프로젝트: abbradar/systemd
static int update_timeout(void) {
        int r;

        if (watchdog_fd < 0)
                return 0;

        if (watchdog_timeout == USEC_INFINITY)
                return 0;
        else if (watchdog_timeout == 0) {
                int flags;

                flags = WDIOS_DISABLECARD;
                r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
                if (r < 0)
                        return log_warning_errno(errno, "Failed to disable hardware watchdog: %m");
        } else {
                int sec, flags;
                char buf[FORMAT_TIMESPAN_MAX];

                sec = (int) ((watchdog_timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
                r = ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &sec);
                if (r < 0)
                        return log_warning_errno(errno, "Failed to set timeout to %is: %m", sec);

                watchdog_timeout = (usec_t) sec * USEC_PER_SEC;
                log_info("Set hardware watchdog to %s.", format_timespan(buf, sizeof(buf), watchdog_timeout, 0));

                flags = WDIOS_ENABLECARD;
                r = ioctl(watchdog_fd, WDIOC_SETOPTIONS, &flags);
                if (r < 0) {
                        /* ENOTTY means the watchdog is always enabled so we're fine */
                        log_full(errno == ENOTTY ? LOG_DEBUG : LOG_WARNING,
                                 "Failed to enable hardware watchdog: %m");
                        if (errno != ENOTTY)
                                return -errno;
                }

                r = ioctl(watchdog_fd, WDIOC_KEEPALIVE, 0);
                if (r < 0)
                        return log_warning_errno(errno, "Failed to ping hardware watchdog: %m");
        }

        return 0;
}
예제 #30
0
static int loop_clients(int accept_fd, uid_t bus_uid) {
        _cleanup_(shared_policy_freep) SharedPolicy *sp = NULL;
        pthread_attr_t attr;
        int r;

        r = pthread_attr_init(&attr);
        if (r != 0)
                return log_error_errno(r, "Cannot initialize pthread attributes: %m");

        r = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
        if (r != 0) {
                r = log_error_errno(r, "Cannot mark pthread attributes as detached: %m");
                goto finish;
        }

        r = shared_policy_new(&sp);
        if (r < 0)
                goto finish;

        for (;;) {
                ClientContext *c;
                pthread_t tid;
                int fd;

                fd = accept4(accept_fd, NULL, NULL, SOCK_NONBLOCK | SOCK_CLOEXEC);
                if (fd < 0) {
                        if (errno == EAGAIN || errno == EINTR)
                                continue;

                        r = log_error_errno(errno, "accept4() failed: %m");
                        goto finish;
                }

                r = client_context_new(&c);
                if (r < 0) {
                        log_oom();
                        close(fd);
                        continue;
                }

                c->fd = fd;
                c->policy = sp;
                c->bus_uid = bus_uid;

                r = pthread_create(&tid, &attr, run_client, c);
                if (r != 0) {
                        log_warning_errno(r, "Cannot spawn thread, ignoring: %m");
                        client_context_free(c);
                        continue;
                }
        }

finish:
        pthread_attr_destroy(&attr);
        return r;
}