Beispiel #1
0
static int test_unit_file_get_set(void) {
        int r;
        Hashmap *h;
        Iterator i;
        UnitFileList *p;

        h = hashmap_new(&string_hash_ops);
        assert_se(h);

        r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);

        if (r == -EPERM || r == -EACCES) {
                printf("Skipping test: unit_file_get_list: %s", strerror(-r));
                return EXIT_TEST_SKIP;
        }

        log_full(r == 0 ? LOG_INFO : LOG_ERR,
                 "unit_file_get_list: %s", strerror(-r));
        if (r < 0)
                return EXIT_FAILURE;

        HASHMAP_FOREACH(p, h, i)
                printf("%s = %s\n", p->path, unit_file_state_to_string(p->state));

        unit_file_list_free(h);

        return 0;
}
Beispiel #2
0
static int mount_one(const MountPoint *p, bool relabel) {
    int r;

    assert(p);

    if (p->condition_fn && !p->condition_fn())
        return 0;

    /* Relabel first, just in case */
    if (relabel)
        label_fix(p->where, true, true);

    r = path_is_mount_point(p->where, true);
    if (r < 0)
        return r;

    if (r > 0)
        return 0;

    /* Skip securityfs in a container */
    if (!(p->mode & MNT_IN_CONTAINER) && detect_container(NULL) > 0)
        return 0;

    /* The access mode here doesn't really matter too much, since
     * the mounted file system will take precedence anyway. */
    if (relabel)
        mkdir_p_label(p->where, 0755);
    else
        mkdir_p(p->where, 0755);

    log_debug("Mounting %s to %s of type %s with options %s.",
              p->what,
              p->where,
              p->type,
              strna(p->options));

    if (mount(p->what,
              p->where,
              p->type,
              p->flags,
              p->options) < 0) {
        log_full((p->mode & MNT_FATAL) ? LOG_ERR : LOG_DEBUG, "Failed to mount %s at %s: %m", p->type, p->where);
        return (p->mode & MNT_FATAL) ? -errno : 0;
    }

    /* Relabel again, since we now mounted something fresh here */
    if (relabel)
        label_fix(p->where, false, false);

    return 1;
}
Beispiel #3
0
int server_open_dev_kmsg(Server *s) {
        mode_t mode;
        int r;

        assert(s);

        if (s->read_kmsg)
                mode = O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY;
        else
                mode = O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY;

        s->dev_kmsg_fd = open("/dev/kmsg", mode);
        if (s->dev_kmsg_fd < 0) {
                log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
                         "Failed to open /dev/kmsg, ignoring: %m");
                return 0;
        }

        if (!s->read_kmsg)
                return 0;

        r = sd_event_add_io(s->event, &s->dev_kmsg_event_source, s->dev_kmsg_fd, EPOLLIN, dispatch_dev_kmsg, s);
        if (r < 0) {

                /* This will fail with EPERM on older kernels where
                 * /dev/kmsg is not readable. */
                if (r == -EPERM) {
                        r = 0;
                        goto fail;
                }

                log_error_errno(r, "Failed to add /dev/kmsg fd to event loop: %m");
                goto fail;
        }

        r = sd_event_source_set_priority(s->dev_kmsg_event_source, SD_EVENT_PRIORITY_IMPORTANT+10);
        if (r < 0) {
                log_error_errno(r, "Failed to adjust priority of kmsg event source: %m");
                goto fail;
        }

        s->dev_kmsg_readable = true;

        return 0;

fail:
        s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);
        s->dev_kmsg_fd = safe_close(s->dev_kmsg_fd);

        return r;
}
Beispiel #4
0
static int hibernation_partition_size(size_t *size, size_t *used) {
        _cleanup_fclose_ FILE *f;
        unsigned i;

        assert(size);
        assert(used);

        f = fopen("/proc/swaps", "re");
        if (!f) {
                log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
                         "Failed to retrieve open /proc/swaps: %m");
                assert(errno > 0);
                return -errno;
        }

        (void) fscanf(f, "%*s %*s %*s %*s %*s\n");

        for (i = 1;; i++) {
                _cleanup_free_ char *dev = NULL, *type = NULL;
                size_t size_field, used_field;
                int k;

                k = fscanf(f,
                           "%ms "   /* device/file */
                           "%ms "   /* type of swap */
                           "%zu "   /* swap size */
                           "%zu "   /* used */
                           "%*i\n", /* priority */
                           &dev, &type, &size_field, &used_field);
                if (k != 4) {
                        if (k == EOF)
                                break;

                        log_warning("Failed to parse /proc/swaps:%u", i);
                        continue;
                }

                if (streq(type, "partition") && endswith(dev, "\\040(deleted)")) {
                        log_warning("Ignoring deleted swapfile '%s'.", dev);
                        continue;
                }

                *size = size_field;
                *used = used_field;
                return 0;
        }

        log_debug("No swap partitions were found.");
        return -ENOSYS;
}
Beispiel #5
0
bool log_event(EventType type, time_t timestamp) {
    if (log_full()) {
        APP_LOG(APP_LOG_LEVEL_ERROR, "log capacity exhausted");
        return false;
    }

    eventLog[(firstEventIdx + eventLogSize++) % EVENT_LOG_MAX_SIZE] = (Event){
        .type = type,
        .timestamp = timestamp
    };

    LOG(APP_LOG_LEVEL_DEBUG, "recorded one event");

    return true;
}
int server_open_dev_kmsg(Server *s) {
        int r;

        assert(s);

        s->dev_kmsg_fd = open("/dev/kmsg", O_RDWR|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
        if (s->dev_kmsg_fd < 0) {
                log_full(errno == ENOENT ? LOG_DEBUG : LOG_WARNING,
                         "Failed to open /dev/kmsg, ignoring: %m");
                return 0;
        }

        r = sd_event_add_io(s->event, &s->dev_kmsg_event_source, s->dev_kmsg_fd, EPOLLIN, dispatch_dev_kmsg, s);
        if (r < 0) {

                /* This will fail with EPERM on older kernels where
                 * /dev/kmsg is not readable. */
                if (r == -EPERM) {
                        r = 0;
                        goto fail;
                }

                log_error("Failed to add /dev/kmsg fd to event loop: %s", strerror(-r));
                goto fail;
        }

        r = sd_event_source_set_priority(s->dev_kmsg_event_source, SD_EVENT_PRIORITY_IMPORTANT+10);
        if (r < 0) {
                log_error("Failed to adjust priority of kmsg event source: %s", strerror(-r));
                goto fail;
        }

        s->dev_kmsg_readable = true;

        return 0;

fail:
        if (s->dev_kmsg_event_source)
                s->dev_kmsg_event_source = sd_event_source_unref(s->dev_kmsg_event_source);

        if (s->dev_kmsg_fd >= 0) {
                close_nointr_nofail(s->dev_kmsg_fd);
                s->dev_kmsg_fd = -1;
        }

        return r;
}
Beispiel #7
0
int label_socket_set(const char *label) {

#ifdef HAVE_SELINUX
        if (!use_selinux())
                return 0;

        if (setsockcreatecon((security_context_t) label) < 0) {
                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
                         "Failed to set SELinux context (%s) on socket: %m", label);

                if (security_getenforce() == 1)
                        return -errno;
        }
#endif

        return 0;
}
Beispiel #8
0
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;
}
Beispiel #9
0
int label_fix(const char *path, bool ignore_enoent) {
        int r = 0;

#ifdef HAVE_SELINUX
        struct stat st;
        security_context_t fcon;

        if (!use_selinux() || !label_hnd)
                return 0;

        r = lstat(path, &st);
        if (r == 0) {
                r = selabel_lookup_raw(label_hnd, &fcon, path, st.st_mode);

                /* If there's no label to set, then exit without warning */
                if (r < 0 && errno == ENOENT)
                        return 0;

                if (r == 0) {
                        r = setfilecon(path, fcon);
                        freecon(fcon);

                        /* If the FS doesn't support labels, then exit without warning */
                        if (r < 0 && errno == ENOTSUP)
                                return 0;
                }
        }

        if (r < 0) {
                /* Ignore ENOENT in some cases */
                if (ignore_enoent && errno == ENOENT)
                        return 0;

                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
                         "Unable to fix label of %s: %m", path);
                r = security_getenforce() == 1 ? -errno : 0;
        }
#endif

        return r;
}
Beispiel #10
0
int label_init(void) {
        int r = 0;

#ifdef HAVE_SELINUX

        if (!use_selinux())
                return 0;

        if (label_hnd)
                return 0;

        label_hnd = selabel_open(SELABEL_CTX_FILE, NULL, 0);
        if (!label_hnd) {
                log_full(security_getenforce() == 1 ? LOG_ERR : LOG_DEBUG,
                         "Failed to initialize SELinux context: %m");
                r = security_getenforce() == 1 ? -errno : 0;
        }
#endif

        return r;
}
Beispiel #11
0
void cryptsetup_log_glue(int level, const char *msg, void *usrptr) {
        switch (level) {
        case CRYPT_LOG_NORMAL:
                level = LOG_NOTICE;
                break;
        case CRYPT_LOG_ERROR:
                level = LOG_ERR;
                break;
        case CRYPT_LOG_VERBOSE:
                level = LOG_INFO;
                break;
        case CRYPT_LOG_DEBUG:
                level = LOG_DEBUG;
                break;
        default:
                log_error("Unknown libcryptsetup log level: %d", level);
                level = LOG_ERR;
        }

        log_full(level, "%s", msg);
}
static int test_unit_file_get_set(void) {
        int r;
        Hashmap *h;
        Iterator i;
        UnitFileList *p;

        h = hashmap_new(string_hash_func, string_compare_func);
        assert(h);

        r = unit_file_get_list(UNIT_FILE_SYSTEM, NULL, h);
        log_full(r == 0 ? LOG_INFO : LOG_ERR,
                 "unit_file_get_list: %s", strerror(-r));
        if (r < 0)
                return EXIT_FAILURE;

        HASHMAP_FOREACH(p, h, i)
                printf("%s = %s\n", p->path, unit_file_state_to_string(p->state));

        unit_file_list_free(h);

        return 0;
}
Beispiel #13
0
/* Go through the file and parse each line */
int config_parse(const char *unit,
                 const char *filename,
                 FILE *f,
                 const char *sections,
                 ConfigItemLookup lookup,
                 const void *table,
                 bool relaxed,
                 bool allow_include,
                 bool warn,
                 void *userdata) {

    _cleanup_free_ char *section = NULL, *continuation = NULL;
    _cleanup_fclose_ FILE *ours = NULL;
    unsigned line = 0, section_line = 0;
    bool section_ignored = false;
    int r;

    assert(filename);
    assert(lookup);

    if (!f) {
        f = ours = fopen(filename, "re");
        if (!f) {
            /* Only log on request, except for ENOENT,
             * since we return 0 to the caller. */
            if (warn || errno == ENOENT)
                log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR,
                         "Failed to open configuration file '%s': %m", filename);
            return errno == ENOENT ? 0 : -errno;
        }
    }

    fd_warn_permissions(filename, fileno(f));

    while (!feof(f)) {
        char l[LINE_MAX], *p, *c = NULL, *e;
        bool escaped = false;

        if (!fgets(l, sizeof(l), f)) {
            if (feof(f))
                break;

            log_error_errno(errno, "Failed to read configuration file '%s': %m", filename);
            return -errno;
        }

        truncate_nl(l);

        if (continuation) {
            c = strappend(continuation, l);
            if (!c) {
                if (warn)
                    log_oom();
                return -ENOMEM;
            }

            continuation = mfree(continuation);
            p = c;
        } else
            p = l;

        for (e = p; *e; e++) {
            if (escaped)
                escaped = false;
            else if (*e == '\\')
                escaped = true;
        }

        if (escaped) {
            *(e-1) = ' ';

            if (c)
                continuation = c;
            else {
                continuation = strdup(l);
                if (!continuation) {
                    if (warn)
                        log_oom();
                    return -ENOMEM;
                }
            }

            continue;
        }

        r = parse_line(unit,
                       filename,
                       ++line,
                       sections,
                       lookup,
                       table,
                       relaxed,
                       allow_include,
                       &section,
                       &section_line,
                       &section_ignored,
                       p,
                       userdata);
        free(c);

        if (r < 0) {
            if (warn)
                log_warning_errno(r, "Failed to parse file '%s': %m",
                                  filename);
            return r;
        }
    }

    return 0;
}
Beispiel #14
0
int parse_sleep_config(const char *verb, char ***_modes, char ***_states) {

        _cleanup_strv_free_ char
                **suspend_mode = NULL, **suspend_state = NULL,
                **hibernate_mode = NULL, **hibernate_state = NULL,
                **hybrid_mode = NULL, **hybrid_state = NULL;
        char **modes, **states;

        const ConfigTableItem items[] = {
                { "Sleep",   "SuspendMode",      config_parse_strv,  0, &suspend_mode  },
                { "Sleep",   "SuspendState",     config_parse_strv,  0, &suspend_state },
                { "Sleep",   "HibernateMode",    config_parse_strv,  0, &hibernate_mode  },
                { "Sleep",   "HibernateState",   config_parse_strv,  0, &hibernate_state },
                { "Sleep",   "HybridSleepMode",  config_parse_strv,  0, &hybrid_mode  },
                { "Sleep",   "HybridSleepState", config_parse_strv,  0, &hybrid_state },
                {}
        };

        int r;
        _cleanup_fclose_ FILE *f;

        f = fopen(PKGSYSCONFDIR "/sleep.conf", "re");
        if (!f)
                log_full(errno == ENOENT ? LOG_DEBUG: LOG_WARNING,
                         "Failed to open configuration file " PKGSYSCONFDIR "/sleep.conf: %m");
        else {
                r = config_parse(NULL, PKGSYSCONFDIR "/sleep.conf", f, "Sleep\0",
                                 config_item_table_lookup, (void*) items, false, false, NULL);
                if (r < 0)
                        log_warning("Failed to parse configuration file: %s", strerror(-r));
        }

        if (streq(verb, "suspend")) {
                /* empty by default */
                USE(modes, suspend_mode);

                if (suspend_state)
                        USE(states, suspend_state);
                else
                        states = strv_new("mem", "standby", "freeze", NULL);

        } else if (streq(verb, "hibernate")) {
                if (hibernate_mode)
                        USE(modes, hibernate_mode);
                else
                        modes = strv_new("platform", "shutdown", NULL);

                if (hibernate_state)
                        USE(states, hibernate_state);
                else
                        states = strv_new("disk", NULL);

        } else if (streq(verb, "hybrid-sleep")) {
                if (hybrid_mode)
                        USE(modes, hybrid_mode);
                else
                        modes = strv_new("suspend", "platform", "shutdown", NULL);

                if (hybrid_state)
                        USE(states, hybrid_state);
                else
                        states = strv_new("disk", NULL);

        } else
                assert_not_reached("what verb");

        if ((!modes && !streq(verb, "suspend")) || !states) {
                strv_free(modes);
                strv_free(states);
                return log_oom();
        }

        *_modes = modes;
        *_states = states;
        return 0;
}
Beispiel #15
0
int journal_directory_vacuum(
                const char *directory,
                uint64_t max_use,
                uint64_t n_max_files,
                usec_t max_retention_usec,
                usec_t *oldest_usec,
                bool verbose) {

        _cleanup_closedir_ DIR *d = NULL;
        struct vacuum_info *list = NULL;
        unsigned n_list = 0, i, n_active_files = 0;
        size_t n_allocated = 0;
        uint64_t sum = 0, freed = 0;
        usec_t retention_limit = 0;
        char sbytes[FORMAT_BYTES_MAX];
        struct dirent *de;
        int r;

        assert(directory);

        if (max_use <= 0 && max_retention_usec <= 0 && n_max_files <= 0)
                return 0;

        if (max_retention_usec > 0) {
                retention_limit = now(CLOCK_REALTIME);
                if (retention_limit > max_retention_usec)
                        retention_limit -= max_retention_usec;
                else
                        max_retention_usec = retention_limit = 0;
        }

        d = opendir(directory);
        if (!d)
                return -errno;

        FOREACH_DIRENT_ALL(de, d, r = -errno; goto finish) {

                unsigned long long seqnum = 0, realtime;
                _cleanup_free_ char *p = NULL;
                sd_id128_t seqnum_id;
                bool have_seqnum;
                uint64_t size;
                struct stat st;
                size_t q;

                if (fstatat(dirfd(d), de->d_name, &st, AT_SYMLINK_NOFOLLOW) < 0) {
                        log_debug_errno(errno, "Failed to stat file %s while vacuuming, ignoring: %m", de->d_name);
                        continue;
                }

                if (!S_ISREG(st.st_mode))
                        continue;

                q = strlen(de->d_name);

                if (endswith(de->d_name, ".journal")) {

                        /* Vacuum archived files. Active files are
                         * left around */

                        if (q < 1 + 32 + 1 + 16 + 1 + 16 + 8) {
                                n_active_files++;
                                continue;
                        }

                        if (de->d_name[q-8-16-1] != '-' ||
                            de->d_name[q-8-16-1-16-1] != '-' ||
                            de->d_name[q-8-16-1-16-1-32-1] != '@') {
                                n_active_files++;
                                continue;
                        }

                        p = strdup(de->d_name);
                        if (!p) {
                                r = -ENOMEM;
                                goto finish;
                        }

                        de->d_name[q-8-16-1-16-1] = 0;
                        if (sd_id128_from_string(de->d_name + q-8-16-1-16-1-32, &seqnum_id) < 0) {
                                n_active_files++;
                                continue;
                        }

                        if (sscanf(de->d_name + q-8-16-1-16, "%16llx-%16llx.journal", &seqnum, &realtime) != 2) {
                                n_active_files++;
                                continue;
                        }

                        have_seqnum = true;

                } else if (endswith(de->d_name, ".journal~")) {
                        unsigned long long tmp;

                        /* Vacuum corrupted files */

                        if (q < 1 + 16 + 1 + 16 + 8 + 1) {
                                n_active_files ++;
                                continue;
                        }

                        if (de->d_name[q-1-8-16-1] != '-' ||
                            de->d_name[q-1-8-16-1-16-1] != '@') {
                                n_active_files ++;
                                continue;
                        }

                        p = strdup(de->d_name);
                        if (!p) {
                                r = -ENOMEM;
                                goto finish;
                        }

                        if (sscanf(de->d_name + q-1-8-16-1-16, "%16llx-%16llx.journal~", &realtime, &tmp) != 2) {
                                n_active_files ++;
                                continue;
                        }

                        have_seqnum = false;
                } else {
                        /* We do not vacuum unknown files! */
                        log_debug("Not vacuuming unknown file %s.", de->d_name);
                        continue;
                }

                size = 512UL * (uint64_t) st.st_blocks;

                r = journal_file_empty(dirfd(d), p);
                if (r < 0) {
                        log_debug_errno(r, "Failed check if %s is empty, ignoring: %m", p);
                        continue;
                }
                if (r > 0) {
                        /* Always vacuum empty non-online files. */

                        if (unlinkat(dirfd(d), p, 0) >= 0) {

                                log_full(verbose ? LOG_INFO : LOG_DEBUG,
                                         "Deleted empty archived journal %s/%s (%s).", directory, p, format_bytes(sbytes, sizeof(sbytes), size));

                                freed += size;
                        } else if (errno != ENOENT)
                                log_warning_errno(errno, "Failed to delete empty archived journal %s/%s: %m", directory, p);

                        continue;
                }

                patch_realtime(dirfd(d), p, &st, &realtime);

                if (!GREEDY_REALLOC(list, n_allocated, n_list + 1)) {
                        r = -ENOMEM;
                        goto finish;
                }

                list[n_list].filename = p;
                list[n_list].usage = size;
                list[n_list].seqnum = seqnum;
                list[n_list].realtime = realtime;
                list[n_list].seqnum_id = seqnum_id;
                list[n_list].have_seqnum = have_seqnum;
                n_list ++;

                p = NULL;
                sum += size;
        }

        qsort_safe(list, n_list, sizeof(struct vacuum_info), vacuum_compare);

        for (i = 0; i < n_list; i++) {
                unsigned left;

                left = n_active_files + n_list - i;

                if ((max_retention_usec <= 0 || list[i].realtime >= retention_limit) &&
                    (max_use <= 0 || sum <= max_use) &&
                    (n_max_files <= 0 || left <= n_max_files))
                        break;

                if (unlinkat(dirfd(d), list[i].filename, 0) >= 0) {
                        log_full(verbose ? LOG_INFO : LOG_DEBUG, "Deleted archived journal %s/%s (%s).", directory, list[i].filename, format_bytes(sbytes, sizeof(sbytes), list[i].usage));
                        freed += list[i].usage;

                        if (list[i].usage < sum)
                                sum -= list[i].usage;
                        else
                                sum = 0;

                } else if (errno != ENOENT)
                        log_warning_errno(errno, "Failed to delete archived journal %s/%s: %m", directory, list[i].filename);
        }

        if (oldest_usec && i < n_list && (*oldest_usec == 0 || list[i].realtime < *oldest_usec))
                *oldest_usec = list[i].realtime;

        r = 0;

finish:
        for (i = 0; i < n_list; i++)
                free(list[i].filename);
        free(list);

        log_full(verbose ? LOG_INFO : LOG_DEBUG, "Vacuuming done, freed %s of archived journals on disk.", format_bytes(sbytes, sizeof(sbytes), freed));

        return r;
}
Beispiel #16
0
int parse_sleep_config(const char *verb, char ***modes, char ***states) {
        _cleanup_strv_free_ char
                **suspend_mode = NULL, **suspend_state = NULL,
                **hibernate_mode = NULL, **hibernate_state = NULL,
                **hybrid_mode = NULL, **hybrid_state = NULL;

        const ConfigTableItem items[] = {
                { "Sleep",   "SuspendMode",      config_parse_strv,  0, &suspend_mode  },
                { "Sleep",   "SuspendState",     config_parse_strv,  0, &suspend_state },
                { "Sleep",   "HibernateMode",    config_parse_strv,  0, &hibernate_mode  },
                { "Sleep",   "HibernateState",   config_parse_strv,  0, &hibernate_state },
                { "Sleep",   "HybridSleepMode",  config_parse_strv,  0, &hybrid_mode  },
                { "Sleep",   "HybridSleepState", config_parse_strv,  0, &hybrid_state },
                {}};

        int r;
        FILE _cleanup_fclose_ *f;

        f = fopen(PKGSYSCONFDIR "/sleep.conf", "re");
        if (!f)
                log_full(errno == ENOENT ? LOG_DEBUG: LOG_WARNING,
                         "Failed to open configuration file " PKGSYSCONFDIR "/sleep.conf: %m");
        else {
                r = config_parse(NULL, PKGSYSCONFDIR "/sleep.conf", f, "Sleep\0",
                                 config_item_table_lookup, (void*) items, false, false, NULL);
                if (r < 0)
                        log_warning("Failed to parse configuration file: %s", strerror(-r));
        }

        if (streq(verb, "suspend")) {
                /* empty by default */
                *modes = suspend_mode;

                if (suspend_state)
                        *states = suspend_state;
                else
                        *states = strv_split_nulstr("mem\0standby\0freeze\0");

                suspend_mode = suspend_state = NULL;
        } else if (streq(verb, "hibernate")) {
                if (hibernate_mode)
                        *modes = hibernate_mode;
                else
                        *modes = strv_split_nulstr("platform\0shutdown\0");

                if (hibernate_state)
                        *states = hibernate_state;
                else
                        *states = strv_split_nulstr("disk\0");

                hibernate_mode = hibernate_state = NULL;
        } else if (streq(verb, "hybrid-sleep")) {
                if (hybrid_mode)
                        *modes = hybrid_mode;
                else
                        *modes = strv_split_nulstr("suspend\0platform\0shutdown\0");

                if (hybrid_state)
                        *states = hybrid_state;
                else
                        *states = strv_split_nulstr("disk\0");

                hybrid_mode = hybrid_state = NULL;
        } else
                assert_not_reached("what verb");

        if (!modes || !states) {
                strv_free(*modes);
                strv_free(*states);
                return log_oom();
        }

        return 0;
}
Beispiel #17
0
/* Go through the file and parse each line */
int config_parse(const char *unit,
                 const char *filename,
                 FILE *f,
                 const char *sections,
                 ConfigItemLookup lookup,
                 const void *table,
                 ConfigParseFlags flags,
                 void *userdata) {

        _cleanup_free_ char *section = NULL, *continuation = NULL;
        _cleanup_fclose_ FILE *ours = NULL;
        unsigned line = 0, section_line = 0;
        bool section_ignored = false;
        int r;

        assert(filename);
        assert(lookup);

        if (!f) {
                f = ours = fopen(filename, "re");
                if (!f) {
                        /* Only log on request, except for ENOENT,
                         * since we return 0 to the caller. */
                        if ((flags & CONFIG_PARSE_WARN) || errno == ENOENT)
                                log_full(errno == ENOENT ? LOG_DEBUG : LOG_ERR,
                                         "Failed to open configuration file '%s': %m", filename);
                        return errno == ENOENT ? 0 : -errno;
                }
        }

        fd_warn_permissions(filename, fileno(f));

        for (;;) {
                _cleanup_free_ char *buf = NULL;
                bool escaped = false;
                char *l, *p, *e;

                r = read_line(f, LONG_LINE_MAX, &buf);
                if (r == 0)
                        break;
                if (r == -ENOBUFS) {
                        if (flags & CONFIG_PARSE_WARN)
                                log_error_errno(r, "%s:%u: Line too long", filename, line);

                        return r;
                }
                if (r < 0) {
                        if (CONFIG_PARSE_WARN)
                                log_error_errno(r, "%s:%u: Error while reading configuration file: %m", filename, line);

                        return r;
                }

                l = buf;
                if (!(flags & CONFIG_PARSE_REFUSE_BOM)) {
                        char *q;

                        q = startswith(buf, UTF8_BYTE_ORDER_MARK);
                        if (q) {
                                l = q;
                                flags |= CONFIG_PARSE_REFUSE_BOM;
                        }
                }

                if (continuation) {
                        if (strlen(continuation) + strlen(l) > LONG_LINE_MAX) {
                                if (flags & CONFIG_PARSE_WARN)
                                        log_error("%s:%u: Continuation line too long", filename, line);
                                return -ENOBUFS;
                        }

                        if (!strextend(&continuation, l, NULL)) {
                                if (flags & CONFIG_PARSE_WARN)
                                        log_oom();
                                return -ENOMEM;
                        }

                        p = continuation;
                } else
                        p = l;

                for (e = p; *e; e++) {
                        if (escaped)
                                escaped = false;
                        else if (*e == '\\')
                                escaped = true;
                }

                if (escaped) {
                        *(e-1) = ' ';

                        if (!continuation) {
                                continuation = strdup(l);
                                if (!continuation) {
                                        if (flags & CONFIG_PARSE_WARN)
                                                log_oom();
                                        return -ENOMEM;
                                }
                        }

                        continue;
                }

                r = parse_line(unit,
                               filename,
                               ++line,
                               sections,
                               lookup,
                               table,
                               flags,
                               &section,
                               &section_line,
                               &section_ignored,
                               p,
                               userdata);
                if (r < 0) {
                        if (flags & CONFIG_PARSE_WARN)
                                log_warning_errno(r, "%s:%u: Failed to parse file: %m", filename, line);
                        return r;

                }

                continuation = mfree(continuation);
        }

        return 0;
}
Beispiel #18
0
/**
* This function is the only log function which should be called from the simulation platform. Actually,
* it is a demultiplexer which calls the correct function depending on the current configuration of the
* platform. Note that this function only returns a pointer to a malloc'd area which contains the
* state buffers. This means that this memory area cannot be used as-is, but should be wrapped
* into a state_t structure, which gives information about the simulation state pointer (defined
* via <SetState>() by the application-level code and the lvt associated with the log.
* This is done implicitly by the <LogState>() function, which in turn connects the newly taken
* snapshot with the currencly-scheduled LP.
* Therefore, any point of the simulator which wants to take a (real) log, shouldn't call directly this
* function, rather <LogState>() should be used, after having correctly set current_lp and current_lvt.
*
* @author Alessandro Pellegrini
*
* @param lid The logical process' local identifier
* @return A pointer to a malloc()'d memory area which contains the log of the current simulation state,
*         along with the relative meta-data which can be used to perform a restore operation.
*/
void *log_state(int lid) {
	statistics_post_lp_data(lid, STAT_CKPT, 1.0);
	return log_full(lid);
}