static int process_dunder(RemoteSource *source, char *line, size_t n) { const char *timestamp; int r; assert(line); assert(n > 0); assert(line[n-1] == '\n'); /* XXX: is it worth to support timestamps in extended format? * We don't produce them, but who knows... */ timestamp = startswith(line, "__CURSOR="); if (timestamp) /* ignore __CURSOR */ return 1; timestamp = startswith(line, "__REALTIME_TIMESTAMP="); if (timestamp) { long long unsigned x; line[n-1] = '\0'; r = safe_atollu(timestamp, &x); if (r < 0) log_warning("Failed to parse __REALTIME_TIMESTAMP: '%s'", timestamp); else source->ts.realtime = x; return r < 0 ? r : 1; } timestamp = startswith(line, "__MONOTONIC_TIMESTAMP="); if (timestamp) { long long unsigned x; line[n-1] = '\0'; r = safe_atollu(timestamp, &x); if (r < 0) log_warning("Failed to parse __MONOTONIC_TIMESTAMP: '%s'", timestamp); else source->ts.monotonic = x; return r < 0 ? r : 1; } timestamp = startswith(line, "__"); if (timestamp) { log_notice("Unknown dunder line %s", line); return 1; } /* no dunder */ return 0; }
static bool enough_memory_for_hibernation(void) { _cleanup_free_ char *active = NULL; unsigned long long act = 0; size_t size = 0, used = 0; int r; r = hibernation_partition_size(&size, &used); if (r < 0) return false; r = get_proc_field("/proc/meminfo", "Active(anon)", WHITESPACE, &active); if (r < 0) { log_error_errno(r, "Failed to retrieve Active(anon) from /proc/meminfo: %m"); return false; } r = safe_atollu(active, &act); if (r < 0) { log_error_errno(r, "Failed to parse Active(anon) from /proc/meminfo: %s: %m", active); return false; } r = act <= (size - used) * HIBERNATION_SWAP_THRESHOLD; log_debug("Hibernation is %spossible, Active(anon)=%llu kB, size=%zu kB, used=%zu kB, threshold=%.2g%%", r ? "" : "im", act, size, used, 100*HIBERNATION_SWAP_THRESHOLD); return r; }
/** * udev_device_get_seqnum: * @udev_device: udev device * * This is only valid if the device was received through a monitor. Devices read from * sys do not have a sequence number. * * Returns: the kernel event sequence number, or 0 if there is no sequence number available. **/ _public_ unsigned long long int udev_device_get_seqnum(struct udev_device *udev_device) { const char *seqnum; unsigned long long ret; int r; assert_return_errno(udev_device, 0, EINVAL); r = sd_device_get_property_value(udev_device->device, "SEQNUM", &seqnum); if (r == -ENOENT) return 0; else if (r < 0) { errno = -r; return 0; } r = safe_atollu(seqnum, &ret); if (r < 0) { errno = -r; return 0; } return ret; }
static int parse_argv(int argc, char *argv[]) { enum { ARG_VERSION = 0x100, ARG_FILES_MAX, ARG_FILE_SIZE_MAX, ARG_TIMEOUT }; static const struct option options[] = { { "help", no_argument, NULL, 'h' }, { "version", no_argument, NULL, ARG_VERSION }, { "files-max", required_argument, NULL, ARG_FILES_MAX }, { "file-size-max", required_argument, NULL, ARG_FILE_SIZE_MAX }, { "timeout", required_argument, NULL, ARG_TIMEOUT }, {} }; int c; assert(argc >= 0); assert(argv); while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) { switch (c) { case 'h': return help(); case ARG_VERSION: puts(PACKAGE_STRING); puts(SYSTEMD_FEATURES); return 0; case ARG_FILES_MAX: if (safe_atou(optarg, &arg_files_max) < 0 || arg_files_max <= 0) { log_error("Failed to parse maximum number of files %s.", optarg); return -EINVAL; } break; case ARG_FILE_SIZE_MAX: { unsigned long long ull; if (safe_atollu(optarg, &ull) < 0 || ull <= 0) { log_error("Failed to parse maximum file size %s.", optarg); return -EINVAL; } arg_file_size_max = (off_t) ull; break; } case ARG_TIMEOUT: if (parse_sec(optarg, &arg_timeout) < 0 || arg_timeout <= 0) { log_error("Failed to parse timeout %s.", optarg); return -EINVAL; } break; case '?': return -EINVAL; default: assert_not_reached("Unhandled option"); } } if (optind != argc-1 && optind != argc-2) { help(); return -EINVAL; } return 1; }
static void dev_kmsg_record(Server *s, const char *p, size_t l) { _cleanup_free_ char *message = NULL, *syslog_priority = NULL, *syslog_pid = NULL, *syslog_facility = NULL, *syslog_identifier = NULL, *source_time = NULL, *identifier = NULL, *pid = NULL; struct iovec iovec[N_IOVEC_META_FIELDS + 7 + N_IOVEC_KERNEL_FIELDS + 2 + N_IOVEC_UDEV_FIELDS]; char *kernel_device = NULL; unsigned long long usec; size_t n = 0, z = 0, j; int priority, r; char *e, *f, *k; uint64_t serial; size_t pl; assert(s); assert(p); if (l <= 0) return; e = memchr(p, ',', l); if (!e) return; *e = 0; r = safe_atoi(p, &priority); if (r < 0 || priority < 0 || priority > 999) return; if (s->forward_to_kmsg && (priority & LOG_FACMASK) != LOG_KERN) return; l -= (e - p) + 1; p = e + 1; e = memchr(p, ',', l); if (!e) return; *e = 0; r = safe_atou64(p, &serial); if (r < 0) return; if (s->kernel_seqnum) { /* We already read this one? */ if (serial < *s->kernel_seqnum) return; /* Did we lose any? */ if (serial > *s->kernel_seqnum) server_driver_message(s, 0, "MESSAGE_ID=" SD_MESSAGE_JOURNAL_MISSED_STR, LOG_MESSAGE("Missed %"PRIu64" kernel messages", serial - *s->kernel_seqnum), NULL); /* Make sure we never read this one again. Note that * we always store the next message serial we expect * here, simply because this makes handling the first * message with serial 0 easy. */ *s->kernel_seqnum = serial + 1; } l -= (e - p) + 1; p = e + 1; f = memchr(p, ';', l); if (!f) return; /* Kernel 3.6 has the flags field, kernel 3.5 lacks that */ e = memchr(p, ',', l); if (!e || f < e) e = f; *e = 0; r = safe_atollu(p, &usec); if (r < 0) return; l -= (f - p) + 1; p = f + 1; e = memchr(p, '\n', l); if (!e) return; *e = 0; pl = e - p; l -= (e - p) + 1; k = e + 1; for (j = 0; l > 0 && j < N_IOVEC_KERNEL_FIELDS; j++) { char *m; /* Metadata fields attached */ if (*k != ' ') break; k++, l--; e = memchr(k, '\n', l); if (!e) return; *e = 0; if (cunescape_length_with_prefix(k, e - k, "_KERNEL_", UNESCAPE_RELAX, &m) < 0) break; if (startswith(m, "_KERNEL_DEVICE=")) kernel_device = m + 15; iovec[n++] = IOVEC_MAKE_STRING(m); z++; l -= (e - k) + 1; k = e + 1; } if (kernel_device) { struct udev_device *ud; ud = udev_device_new_from_device_id(s->udev, kernel_device); if (ud) { const char *g; struct udev_list_entry *ll; char *b; g = udev_device_get_devnode(ud); if (g) { b = strappend("_UDEV_DEVNODE=", g); if (b) { iovec[n++] = IOVEC_MAKE_STRING(b); z++; } } g = udev_device_get_sysname(ud); if (g) { b = strappend("_UDEV_SYSNAME=", g); if (b) { iovec[n++] = IOVEC_MAKE_STRING(b); z++; } } j = 0; ll = udev_device_get_devlinks_list_entry(ud); udev_list_entry_foreach(ll, ll) { if (j > N_IOVEC_UDEV_FIELDS) break; g = udev_list_entry_get_name(ll); if (g) { b = strappend("_UDEV_DEVLINK=", g); if (b) { iovec[n++] = IOVEC_MAKE_STRING(b); z++; } } j++; } udev_device_unref(ud); } } if (asprintf(&source_time, "_SOURCE_MONOTONIC_TIMESTAMP=%llu", usec) >= 0) iovec[n++] = IOVEC_MAKE_STRING(source_time); iovec[n++] = IOVEC_MAKE_STRING("_TRANSPORT=kernel"); if (asprintf(&syslog_priority, "PRIORITY=%i", priority & LOG_PRIMASK) >= 0) iovec[n++] = IOVEC_MAKE_STRING(syslog_priority); if (asprintf(&syslog_facility, "SYSLOG_FACILITY=%i", LOG_FAC(priority)) >= 0) iovec[n++] = IOVEC_MAKE_STRING(syslog_facility); if ((priority & LOG_FACMASK) == LOG_KERN) iovec[n++] = IOVEC_MAKE_STRING("SYSLOG_IDENTIFIER=kernel"); else { pl -= syslog_parse_identifier((const char**) &p, &identifier, &pid); /* Avoid any messages we generated ourselves via * log_info() and friends. */ if (pid && is_us(pid)) goto finish; if (identifier) { syslog_identifier = strappend("SYSLOG_IDENTIFIER=", identifier); if (syslog_identifier) iovec[n++] = IOVEC_MAKE_STRING(syslog_identifier); } if (pid) { syslog_pid = strappend("SYSLOG_PID=", pid); if (syslog_pid) iovec[n++] = IOVEC_MAKE_STRING(syslog_pid); } } if (cunescape_length_with_prefix(p, pl, "MESSAGE=", UNESCAPE_RELAX, &message) >= 0) iovec[n++] = IOVEC_MAKE_STRING(message); server_dispatch_message(s, iovec, n, ELEMENTSOF(iovec), NULL, NULL, priority, 0); finish: for (j = 0; j < z; j++) free(iovec[j].iov_base); }