mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-24 21:34:08 +03:00
Merge branch 'journal'
This commit is contained in:
commit
dc1ecd78e9
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,3 +1,9 @@
|
|||||||
|
/libsystemd-journal.pc
|
||||||
|
/libsystemd-id128.pc
|
||||||
|
systemd-journalctl
|
||||||
|
systemd-journald
|
||||||
|
test-id128
|
||||||
|
test-journal
|
||||||
test-install
|
test-install
|
||||||
org.freedesktop.hostname1.xml
|
org.freedesktop.hostname1.xml
|
||||||
org.freedesktop.locale1.xml
|
org.freedesktop.locale1.xml
|
||||||
@ -91,7 +97,7 @@ install-sh
|
|||||||
missing
|
missing
|
||||||
stamp-*
|
stamp-*
|
||||||
*.stamp
|
*.stamp
|
||||||
Makefile
|
/Makefile
|
||||||
ltmain.sh
|
ltmain.sh
|
||||||
*.tar.bz2
|
*.tar.bz2
|
||||||
*.tar.gz
|
*.tar.gz
|
||||||
|
262
Makefile.am
262
Makefile.am
@ -27,6 +27,14 @@ LIBSYSTEMD_DAEMON_CURRENT=0
|
|||||||
LIBSYSTEMD_DAEMON_REVISION=0
|
LIBSYSTEMD_DAEMON_REVISION=0
|
||||||
LIBSYSTEMD_DAEMON_AGE=0
|
LIBSYSTEMD_DAEMON_AGE=0
|
||||||
|
|
||||||
|
LIBSYSTEMD_ID128_CURRENT=0
|
||||||
|
LIBSYSTEMD_ID128_REVISION=0
|
||||||
|
LIBSYSTEMD_ID128_AGE=0
|
||||||
|
|
||||||
|
LIBSYSTEMD_JOURNAL_CURRENT=0
|
||||||
|
LIBSYSTEMD_JOURNAL_REVISION=0
|
||||||
|
LIBSYSTEMD_JOURNAL_AGE=0
|
||||||
|
|
||||||
# Dirs of external packages
|
# Dirs of external packages
|
||||||
dbuspolicydir=@dbuspolicydir@
|
dbuspolicydir=@dbuspolicydir@
|
||||||
dbussessionservicedir=@dbussessionservicedir@
|
dbussessionservicedir=@dbussessionservicedir@
|
||||||
@ -141,7 +149,8 @@ rootbin_PROGRAMS = \
|
|||||||
systemd-ask-password \
|
systemd-ask-password \
|
||||||
systemd-tty-ask-password-agent \
|
systemd-tty-ask-password-agent \
|
||||||
systemd-tmpfiles \
|
systemd-tmpfiles \
|
||||||
systemd-machine-id-setup
|
systemd-machine-id-setup \
|
||||||
|
systemd-journalctl
|
||||||
|
|
||||||
bin_PROGRAMS = \
|
bin_PROGRAMS = \
|
||||||
systemd-cgls \
|
systemd-cgls \
|
||||||
@ -180,7 +189,8 @@ rootlibexec_PROGRAMS = \
|
|||||||
systemd-detect-virt \
|
systemd-detect-virt \
|
||||||
systemd-sysctl \
|
systemd-sysctl \
|
||||||
systemd-logind \
|
systemd-logind \
|
||||||
systemd-uaccess
|
systemd-uaccess \
|
||||||
|
systemd-journald
|
||||||
|
|
||||||
if ENABLE_BINFMT
|
if ENABLE_BINFMT
|
||||||
rootlibexec_PROGRAMS += \
|
rootlibexec_PROGRAMS += \
|
||||||
@ -215,11 +225,15 @@ endif
|
|||||||
|
|
||||||
lib_LTLIBRARIES = \
|
lib_LTLIBRARIES = \
|
||||||
libsystemd-daemon.la \
|
libsystemd-daemon.la \
|
||||||
libsystemd-login.la
|
libsystemd-login.la \
|
||||||
|
libsystemd-id128.la \
|
||||||
|
libsystemd-journal.la
|
||||||
|
|
||||||
pkginclude_HEADERS = \
|
pkginclude_HEADERS = \
|
||||||
src/sd-daemon.h \
|
src/sd-daemon.h \
|
||||||
src/sd-login.h
|
src/sd-login.h \
|
||||||
|
src/sd-id128.h \
|
||||||
|
src/journal/sd-journal.h
|
||||||
|
|
||||||
noinst_PROGRAMS = \
|
noinst_PROGRAMS = \
|
||||||
test-engine \
|
test-engine \
|
||||||
@ -232,7 +246,9 @@ noinst_PROGRAMS = \
|
|||||||
test-env-replace \
|
test-env-replace \
|
||||||
test-strv \
|
test-strv \
|
||||||
test-login \
|
test-login \
|
||||||
test-install
|
test-install \
|
||||||
|
test-id128 \
|
||||||
|
test-journal
|
||||||
|
|
||||||
if HAVE_PAM
|
if HAVE_PAM
|
||||||
pamlib_LTLIBRARIES = \
|
pamlib_LTLIBRARIES = \
|
||||||
@ -385,7 +401,8 @@ dist_systemunit_DATA = \
|
|||||||
units/quotaon.service \
|
units/quotaon.service \
|
||||||
units/systemd-ask-password-wall.path \
|
units/systemd-ask-password-wall.path \
|
||||||
units/systemd-ask-password-console.path \
|
units/systemd-ask-password-console.path \
|
||||||
units/syslog.target
|
units/syslog.target \
|
||||||
|
units/systemd-journald.socket
|
||||||
|
|
||||||
if HAVE_SYSV_COMPAT
|
if HAVE_SYSV_COMPAT
|
||||||
dist_systemunit_DATA += \
|
dist_systemunit_DATA += \
|
||||||
@ -406,6 +423,7 @@ nodist_systemunit_DATA = \
|
|||||||
units/systemd-stdout-syslog-bridge.service \
|
units/systemd-stdout-syslog-bridge.service \
|
||||||
units/systemd-shutdownd.service \
|
units/systemd-shutdownd.service \
|
||||||
units/systemd-logind.service \
|
units/systemd-logind.service \
|
||||||
|
units/systemd-journald.service \
|
||||||
units/systemd-kmsg-syslogd.service \
|
units/systemd-kmsg-syslogd.service \
|
||||||
units/systemd-modules-load.service \
|
units/systemd-modules-load.service \
|
||||||
units/systemd-vconsole-setup.service \
|
units/systemd-vconsole-setup.service \
|
||||||
@ -469,7 +487,8 @@ EXTRA_DIST = \
|
|||||||
units/systemd-stdout-syslog-bridge.service.in \
|
units/systemd-stdout-syslog-bridge.service.in \
|
||||||
units/systemd-shutdownd.service.in \
|
units/systemd-shutdownd.service.in \
|
||||||
units/systemd-logind.service.in \
|
units/systemd-logind.service.in \
|
||||||
units/systemd-kmsg-syslogd.service.in \
|
units/systemd-journald.service.in \
|
||||||
|
units/systemd-kmsg-syslogd.service.in \
|
||||||
units/systemd-modules-load.service.in \
|
units/systemd-modules-load.service.in \
|
||||||
units/systemd-vconsole-setup.service.in \
|
units/systemd-vconsole-setup.service.in \
|
||||||
units/systemd-remount-api-vfs.service.in \
|
units/systemd-remount-api-vfs.service.in \
|
||||||
@ -498,11 +517,16 @@ EXTRA_DIST = \
|
|||||||
systemd.pc.in \
|
systemd.pc.in \
|
||||||
libsystemd-daemon.pc.in \
|
libsystemd-daemon.pc.in \
|
||||||
libsystemd-login.pc.in \
|
libsystemd-login.pc.in \
|
||||||
|
libsystemd-id128.pc.in \
|
||||||
|
libsystemd-journal.pc.in \
|
||||||
src/libsystemd-daemon.sym \
|
src/libsystemd-daemon.sym \
|
||||||
src/libsystemd-login.sym \
|
src/libsystemd-login.sym \
|
||||||
|
src/libsystemd-id128.sym \
|
||||||
|
src/libsystemd-journal.sym \
|
||||||
introspect.awk \
|
introspect.awk \
|
||||||
src/73-seat-late.rules.in \
|
src/73-seat-late.rules.in \
|
||||||
src/99-systemd.rules.in
|
src/99-systemd.rules.in \
|
||||||
|
man/custom-html.xsl
|
||||||
|
|
||||||
if ENABLE_BINFMT
|
if ENABLE_BINFMT
|
||||||
EXTRA_DIST += \
|
EXTRA_DIST += \
|
||||||
@ -597,7 +621,9 @@ pkgconfigdata_DATA = \
|
|||||||
|
|
||||||
pkgconfiglib_DATA = \
|
pkgconfiglib_DATA = \
|
||||||
libsystemd-daemon.pc \
|
libsystemd-daemon.pc \
|
||||||
libsystemd-login.pc
|
libsystemd-login.pc \
|
||||||
|
libsystemd-id128.pc \
|
||||||
|
libsystemd-journal.pc
|
||||||
|
|
||||||
# Passed through intltool only
|
# Passed through intltool only
|
||||||
polkitpolicy_in_files = \
|
polkitpolicy_in_files = \
|
||||||
@ -709,7 +735,8 @@ libsystemd_core_la_SOURCES = \
|
|||||||
src/dbus-common.c \
|
src/dbus-common.c \
|
||||||
src/sd-daemon.c \
|
src/sd-daemon.c \
|
||||||
src/install.c \
|
src/install.c \
|
||||||
src/cgroup-attr.c
|
src/cgroup-attr.c \
|
||||||
|
src/sd-id128.c
|
||||||
|
|
||||||
nodist_libsystemd_core_la_SOURCES = \
|
nodist_libsystemd_core_la_SOURCES = \
|
||||||
src/load-fragment-gperf.c \
|
src/load-fragment-gperf.c \
|
||||||
@ -772,7 +799,14 @@ EXTRA_DIST += \
|
|||||||
src/logind-user.h \
|
src/logind-user.h \
|
||||||
src/logind-acl.h \
|
src/logind-acl.h \
|
||||||
src/dbus-loop.h \
|
src/dbus-loop.h \
|
||||||
src/spawn-agent.h
|
src/spawn-agent.h \
|
||||||
|
src/journal/journal-def.h \
|
||||||
|
src/journal/journal-internal.h \
|
||||||
|
src/journal/journal-file.h \
|
||||||
|
src/journal/lookup3.h \
|
||||||
|
src/journal/compress.h \
|
||||||
|
src/journal/journal-rate-limit.h \
|
||||||
|
src/acl-util.h
|
||||||
|
|
||||||
MANPAGES = \
|
MANPAGES = \
|
||||||
man/systemd.1 \
|
man/systemd.1 \
|
||||||
@ -802,6 +836,7 @@ MANPAGES = \
|
|||||||
man/daemon.7 \
|
man/daemon.7 \
|
||||||
man/sd-daemon.7 \
|
man/sd-daemon.7 \
|
||||||
man/sd-readahead.7 \
|
man/sd-readahead.7 \
|
||||||
|
man/sd-login.7 \
|
||||||
man/runlevel.8 \
|
man/runlevel.8 \
|
||||||
man/telinit.8 \
|
man/telinit.8 \
|
||||||
man/halt.8 \
|
man/halt.8 \
|
||||||
@ -820,7 +855,13 @@ MANPAGES = \
|
|||||||
man/modules-load.d.5 \
|
man/modules-load.d.5 \
|
||||||
man/sysctl.d.5 \
|
man/sysctl.d.5 \
|
||||||
man/systemd-ask-password.1 \
|
man/systemd-ask-password.1 \
|
||||||
man/systemd-loginctl.1
|
man/systemd-loginctl.1 \
|
||||||
|
man/sd_pid_get_session.3 \
|
||||||
|
man/sd_uid_get_state.3 \
|
||||||
|
man/sd_session_is_active.3 \
|
||||||
|
man/sd_seat_get_active.3 \
|
||||||
|
man/sd_get_seats.3 \
|
||||||
|
man/sd_login_monitor_new.3
|
||||||
|
|
||||||
if ENABLE_BINFMT
|
if ENABLE_BINFMT
|
||||||
MANPAGES += \
|
MANPAGES += \
|
||||||
@ -833,16 +874,44 @@ MANPAGES_ALIAS = \
|
|||||||
man/sd_is_socket.3 \
|
man/sd_is_socket.3 \
|
||||||
man/sd_is_socket_unix.3 \
|
man/sd_is_socket_unix.3 \
|
||||||
man/sd_is_socket_inet.3 \
|
man/sd_is_socket_inet.3 \
|
||||||
|
man/sd_is_mq.3 \
|
||||||
man/sd_notifyf.3 \
|
man/sd_notifyf.3 \
|
||||||
man/init.1
|
man/init.1 \
|
||||||
|
man/sd_session_get_uid.3 \
|
||||||
|
man/sd_session_get_seat.3 \
|
||||||
|
man/sd_pid_get_owner_uid.3 \
|
||||||
|
man/sd_uid_is_on_seat.3 \
|
||||||
|
man/sd_uid_get_sessions.3 \
|
||||||
|
man/sd_uid_get_seats.3 \
|
||||||
|
man/sd_seat_get_sessions.3 \
|
||||||
|
man/sd_seat_can_multi_session.3 \
|
||||||
|
man/sd_get_sessions.3 \
|
||||||
|
man/sd_get_uids.3 \
|
||||||
|
man/sd_login_monitor_unref.3 \
|
||||||
|
man/sd_login_monitor_flush.3 \
|
||||||
|
man/sd_login_monitor_get_fd.3
|
||||||
|
|
||||||
man/reboot.8: man/halt.8
|
man/reboot.8: man/halt.8
|
||||||
man/poweroff.8: man/halt.8
|
man/poweroff.8: man/halt.8
|
||||||
man/sd_is_socket.3: man/sd_is_fifo.3
|
man/sd_is_socket.3: man/sd_is_fifo.3
|
||||||
man/sd_is_socket_unix.3: man/sd_is_fifo.3
|
man/sd_is_socket_unix.3: man/sd_is_fifo.3
|
||||||
man/sd_is_socket_inet.3: man/sd_is_fifo.3
|
man/sd_is_socket_inet.3: man/sd_is_fifo.3
|
||||||
|
man/sd_is_mq.3: man/sd_is_fifo.3
|
||||||
man/sd_notifyf.3: man/sd_notify.3
|
man/sd_notifyf.3: man/sd_notify.3
|
||||||
man/init.1: man/systemd.1
|
man/init.1: man/systemd.1
|
||||||
|
man/sd_session_get_uid.3: man/sd_session_is_active.3
|
||||||
|
man/sd_session_get_seat.3: man/sd_session_is_active.3
|
||||||
|
man/sd_pid_get_owner_uid.3: man/sd_pid_get_session.3
|
||||||
|
man/sd_uid_is_on_seat.3: man/sd_uid_get_state.3
|
||||||
|
man/sd_uid_get_sessions.3: man/sd_uid_get_state.3
|
||||||
|
man/sd_uid_get_seats.3: man/sd_uid_get_state.3
|
||||||
|
man/sd_seat_get_sessions.3: man/sd_seat_get_active.3
|
||||||
|
man/sd_seat_can_multi_session.3: man/sd_seat_get_active.3
|
||||||
|
man/sd_get_sessions.3: man/sd_get_seats.3
|
||||||
|
man/sd_get_uids.3: man/sd_get_seats.3
|
||||||
|
man/sd_login_monitor_unref.3: man/sd_login_monitor_new.3
|
||||||
|
man/sd_login_monitor_flush.3: man/sd_login_monitor_new.3
|
||||||
|
man/sd_login_monitor_get_fd.3: man/sd_login_monitor_new.3
|
||||||
|
|
||||||
dist_man_MANS = \
|
dist_man_MANS = \
|
||||||
$(MANPAGES) \
|
$(MANPAGES) \
|
||||||
@ -971,6 +1040,90 @@ test_install_CFLAGS = \
|
|||||||
test_install_LDADD = \
|
test_install_LDADD = \
|
||||||
libsystemd-basic.la
|
libsystemd-basic.la
|
||||||
|
|
||||||
|
test_id128_SOURCES = \
|
||||||
|
src/test-id128.c \
|
||||||
|
src/sd-id128.c
|
||||||
|
|
||||||
|
test_id128_CFLAGS = \
|
||||||
|
$(AM_CFLAGS)
|
||||||
|
|
||||||
|
test_id128_LDADD = \
|
||||||
|
libsystemd-basic.la
|
||||||
|
|
||||||
|
test_journal_SOURCES = \
|
||||||
|
src/journal/test-journal.c \
|
||||||
|
src/journal/sd-journal.c \
|
||||||
|
src/journal/journal-file.c \
|
||||||
|
src/journal/lookup3.c \
|
||||||
|
src/journal/journal-send.c \
|
||||||
|
src/sd-id128.c
|
||||||
|
|
||||||
|
test_journal_CFLAGS = \
|
||||||
|
$(AM_CFLAGS)
|
||||||
|
|
||||||
|
test_journal_LDADD = \
|
||||||
|
libsystemd-basic.la
|
||||||
|
|
||||||
|
if HAVE_XZ
|
||||||
|
test_journal_SOURCES += \
|
||||||
|
src/journal/compress.c
|
||||||
|
test_journal_CFLAGS += \
|
||||||
|
$(XZ_CFLAGS)
|
||||||
|
test_journal_LDADD += \
|
||||||
|
$(XZ_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
systemd_journald_SOURCES = \
|
||||||
|
src/journal/journald.c \
|
||||||
|
src/journal/sd-journal.c \
|
||||||
|
src/journal/journal-file.c \
|
||||||
|
src/journal/lookup3.c \
|
||||||
|
src/journal/journal-rate-limit.c \
|
||||||
|
src/sd-id128.c \
|
||||||
|
src/acl-util.c \
|
||||||
|
src/cgroup-util.c
|
||||||
|
|
||||||
|
systemd_journald_CFLAGS = \
|
||||||
|
$(AM_CFLAGS) \
|
||||||
|
$(ACL_CFLAGS)
|
||||||
|
|
||||||
|
systemd_journald_LDADD = \
|
||||||
|
libsystemd-basic.la \
|
||||||
|
libsystemd-daemon.la \
|
||||||
|
$(ACL_LIBS)
|
||||||
|
|
||||||
|
if HAVE_XZ
|
||||||
|
systemd_journald_SOURCES += \
|
||||||
|
src/journal/compress.c
|
||||||
|
systemd_journald_CFLAGS += \
|
||||||
|
$(XZ_CFLAGS)
|
||||||
|
systemd_journald_LDADD += \
|
||||||
|
$(XZ_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
|
systemd_journalctl_SOURCES = \
|
||||||
|
src/journal/journalctl.c \
|
||||||
|
src/journal/sd-journal.c \
|
||||||
|
src/journal/journal-file.c \
|
||||||
|
src/journal/lookup3.c \
|
||||||
|
src/sd-id128.c \
|
||||||
|
src/pager.c
|
||||||
|
|
||||||
|
systemd_journalctl_CFLAGS = \
|
||||||
|
$(AM_CFLAGS)
|
||||||
|
|
||||||
|
systemd_journalctl_LDADD = \
|
||||||
|
libsystemd-basic.la
|
||||||
|
|
||||||
|
if HAVE_XZ
|
||||||
|
systemd_journalctl_SOURCES += \
|
||||||
|
src/journal/compress.c
|
||||||
|
systemd_journalctl_CFLAGS += \
|
||||||
|
$(XZ_CFLAGS)
|
||||||
|
systemd_journalctl_LDADD += \
|
||||||
|
$(XZ_LIBS)
|
||||||
|
endif
|
||||||
|
|
||||||
systemd_stdout_syslog_bridge_SOURCES = \
|
systemd_stdout_syslog_bridge_SOURCES = \
|
||||||
src/stdout-syslog-bridge.c \
|
src/stdout-syslog-bridge.c \
|
||||||
src/tcpwrap.c
|
src/tcpwrap.c
|
||||||
@ -1115,10 +1268,12 @@ systemd_uaccess_SOURCES = \
|
|||||||
|
|
||||||
if HAVE_ACL
|
if HAVE_ACL
|
||||||
systemd_logind_SOURCES += \
|
systemd_logind_SOURCES += \
|
||||||
src/logind-acl.c
|
src/logind-acl.c \
|
||||||
|
src/acl-util.c
|
||||||
|
|
||||||
systemd_uaccess_SOURCES += \
|
systemd_uaccess_SOURCES += \
|
||||||
src/logind-acl.c
|
src/logind-acl.c \
|
||||||
|
src/acl-util.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
systemd_uaccess_CFLAGS = \
|
systemd_uaccess_CFLAGS = \
|
||||||
@ -1166,7 +1321,8 @@ systemd_tmpfiles_LDADD = \
|
|||||||
|
|
||||||
systemd_machine_id_setup_SOURCES = \
|
systemd_machine_id_setup_SOURCES = \
|
||||||
src/machine-id-setup.c \
|
src/machine-id-setup.c \
|
||||||
src/machine-id-main.c
|
src/machine-id-main.c \
|
||||||
|
src/sd-id128.c
|
||||||
|
|
||||||
systemd_machine_id_setup_CFLAGS = \
|
systemd_machine_id_setup_CFLAGS = \
|
||||||
$(AM_CFLAGS)
|
$(AM_CFLAGS)
|
||||||
@ -1592,6 +1748,69 @@ libsystemd-login-install-hook:
|
|||||||
libsystemd-login-uninstall-hook:
|
libsystemd-login-uninstall-hook:
|
||||||
rm -f $(DESTDIR)$(rootlibdir)/libsystemd-login.so*
|
rm -f $(DESTDIR)$(rootlibdir)/libsystemd-login.so*
|
||||||
|
|
||||||
|
libsystemd_id128_la_SOURCES = \
|
||||||
|
src/sd-id128.c
|
||||||
|
|
||||||
|
libsystemd_id128_la_CFLAGS = \
|
||||||
|
$(AM_CFLAGS) \
|
||||||
|
-fvisibility=hidden
|
||||||
|
|
||||||
|
libsystemd_id128_la_LDFLAGS = \
|
||||||
|
-shared \
|
||||||
|
-version-info $(LIBSYSTEMD_ID128_CURRENT):$(LIBSYSTEMD_ID128_REVISION):$(LIBSYSTEMD_ID128_AGE) \
|
||||||
|
-Wl,--version-script=$(top_srcdir)/src/libsystemd-id128.sym
|
||||||
|
|
||||||
|
libsystemd_id128_la_LIBADD = \
|
||||||
|
libsystemd-basic.la
|
||||||
|
|
||||||
|
# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
|
||||||
|
libsystemd-id128-install-hook:
|
||||||
|
if test "$(libdir)" != "$(rootlibdir)"; then \
|
||||||
|
mkdir -p $(DESTDIR)$(rootlibdir) && \
|
||||||
|
so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-id128.so) && \
|
||||||
|
so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
|
||||||
|
ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-id128.so && \
|
||||||
|
mv $(DESTDIR)$(libdir)/libsystemd-id128.so.* $(DESTDIR)$(rootlibdir); \
|
||||||
|
fi
|
||||||
|
|
||||||
|
libsystemd-id128-uninstall-hook:
|
||||||
|
rm -f $(DESTDIR)$(rootlibdir)/libsystemd-id128.so*
|
||||||
|
|
||||||
|
libsystemd_journal_la_SOURCES = \
|
||||||
|
src/journal/sd-journal.c \
|
||||||
|
src/journal/journal-file.c \
|
||||||
|
src/journal/compress.c \
|
||||||
|
src/journal/lookup3.c \
|
||||||
|
src/journal/journal-send.c
|
||||||
|
|
||||||
|
libsystemd_journal_la_CFLAGS = \
|
||||||
|
$(AM_CFLAGS) \
|
||||||
|
$(XZ_CFLAGS) \
|
||||||
|
-fvisibility=hidden
|
||||||
|
|
||||||
|
libsystemd_journal_la_LDFLAGS = \
|
||||||
|
-shared \
|
||||||
|
-version-info $(LIBSYSTEMD_JOURNAL_CURRENT):$(LIBSYSTEMD_JOURNAL_REVISION):$(LIBSYSTEMD_JOURNAL_AGE) \
|
||||||
|
-Wl,--version-script=$(top_srcdir)/src/libsystemd-journal.sym
|
||||||
|
|
||||||
|
libsystemd_journal_la_LIBADD = \
|
||||||
|
libsystemd-basic.la \
|
||||||
|
libsystemd-id128.la \
|
||||||
|
$(XZ_LIBS)
|
||||||
|
|
||||||
|
# move lib from $(libdir) to $(rootlibdir) and update devel link, if needed
|
||||||
|
libsystemd-journal-install-hook:
|
||||||
|
if test "$(libdir)" != "$(rootlibdir)"; then \
|
||||||
|
mkdir -p $(DESTDIR)$(rootlibdir) && \
|
||||||
|
so_img_name=$$(readlink $(DESTDIR)$(libdir)/libsystemd-journal.so) && \
|
||||||
|
so_img_rel_target_prefix=$$(echo $(libdir) | sed 's,\(^/\|\)[^/][^/]*,..,g') && \
|
||||||
|
ln -sf $$so_img_rel_target_prefix$(rootlibdir)/$$so_img_name $(DESTDIR)$(libdir)/libsystemd-journal.so && \
|
||||||
|
mv $(DESTDIR)$(libdir)/libsystemd-journal.so.* $(DESTDIR)$(rootlibdir); \
|
||||||
|
fi
|
||||||
|
|
||||||
|
libsystemd-journal-uninstall-hook:
|
||||||
|
rm -f $(DESTDIR)$(rootlibdir)/libsystemd-journal.so*
|
||||||
|
|
||||||
SED_PROCESS = \
|
SED_PROCESS = \
|
||||||
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
||||||
$(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \
|
$(SED) -e 's,@rootlibexecdir\@,$(rootlibexecdir),g' \
|
||||||
@ -1677,7 +1896,7 @@ endif
|
|||||||
if HAVE_XSLTPROC
|
if HAVE_XSLTPROC
|
||||||
XSLTPROC_FLAGS = \
|
XSLTPROC_FLAGS = \
|
||||||
--nonet \
|
--nonet \
|
||||||
--param funcsynopsis.style "'ansi'"
|
--stringparam funcsynopsis.style ansi
|
||||||
|
|
||||||
XSLTPROC_PROCESS_MAN = \
|
XSLTPROC_PROCESS_MAN = \
|
||||||
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
||||||
@ -1690,11 +1909,11 @@ XSLTPROC_PROCESS_MAN_IN = \
|
|||||||
|
|
||||||
XSLTPROC_PROCESS_HTML = \
|
XSLTPROC_PROCESS_HTML = \
|
||||||
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
||||||
$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/xhtml-1_1/docbook.xsl $<
|
$(XSLTPROC) -o $@ $(XSLTPROC_FLAGS) man/custom-html.xsl $<
|
||||||
|
|
||||||
XSLTPROC_PROCESS_HTML_IN = \
|
XSLTPROC_PROCESS_HTML_IN = \
|
||||||
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
$(AM_V_GEN)$(MKDIR_P) $(dir $@) && \
|
||||||
$(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) http://docbook.sourceforge.net/release/xsl/current/xhtml-1_1/docbook.xsl $< && \
|
$(XSLTPROC) -o ${@:.in=} $(XSLTPROC_FLAGS) man/custom-html.xsl $< && \
|
||||||
mv ${@:.in=} $@
|
mv ${@:.in=} $@
|
||||||
|
|
||||||
man/%.1: man/%.xml
|
man/%.1: man/%.xml
|
||||||
@ -1808,11 +2027,12 @@ endif
|
|||||||
rm -f user && \
|
rm -f user && \
|
||||||
$(LN_S) $(pkgsysconfdir)/user user )
|
$(LN_S) $(pkgsysconfdir)/user user )
|
||||||
( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \
|
( cd $(DESTDIR)$(systemunitdir)/sockets.target.wants && \
|
||||||
rm -f systemd-initctl.socket systemd-stdout-syslog-bridge.socket systemd-shutdownd.socket syslog.socket && \
|
rm -f systemd-initctl.socket systemd-stdout-syslog-bridge.socket systemd-shutdownd.socket syslog.socket systemd-journald.socket && \
|
||||||
$(LN_S) ../systemd-stdout-syslog-bridge.socket systemd-stdout-syslog-bridge.socket && \
|
$(LN_S) ../systemd-stdout-syslog-bridge.socket systemd-stdout-syslog-bridge.socket && \
|
||||||
$(LN_S) ../systemd-initctl.socket systemd-initctl.socket && \
|
$(LN_S) ../systemd-initctl.socket systemd-initctl.socket && \
|
||||||
$(LN_S) ../systemd-shutdownd.socket systemd-shutdownd.socket && \
|
$(LN_S) ../systemd-shutdownd.socket systemd-shutdownd.socket && \
|
||||||
$(LN_S) ../syslog.socket syslog.socket )
|
$(LN_S) ../syslog.socket syslog.socket && \
|
||||||
|
$(LN_S) ../systemd-journald.socket )
|
||||||
( cd $(DESTDIR)$(systemunitdir)/runlevel1.target.wants && \
|
( cd $(DESTDIR)$(systemunitdir)/runlevel1.target.wants && \
|
||||||
rm -f systemd-update-utmp-runlevel.service && \
|
rm -f systemd-update-utmp-runlevel.service && \
|
||||||
$(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service )
|
$(LN_S) ../systemd-update-utmp-runlevel.service systemd-update-utmp-runlevel.service )
|
||||||
|
12
TODO
12
TODO
@ -17,8 +17,20 @@ Bugfixes:
|
|||||||
|
|
||||||
* make polkit checks async
|
* make polkit checks async
|
||||||
|
|
||||||
|
* properly handle .mount unit state tracking when two mount points are stacked one on top of another on the exact same mount point.
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
|
|
||||||
|
* logind: selinux is borked...
|
||||||
|
|
||||||
|
* logind: sends SessionNew on Lock()?
|
||||||
|
|
||||||
|
* logind: allow showing logout dialog from system
|
||||||
|
|
||||||
|
* document that %% can be used to write % in a string that is specifier extended
|
||||||
|
|
||||||
|
* check utf8 everywhere
|
||||||
|
|
||||||
* when an instanced service exits, remove its parent cgroup too if possible.
|
* when an instanced service exits, remove its parent cgroup too if possible.
|
||||||
|
|
||||||
* Make libselinux, libattr, libcap, libdl dependencies only of the tools which actually need them.
|
* Make libselinux, libattr, libcap, libdl dependencies only of the tools which actually need them.
|
||||||
|
14
configure.ac
14
configure.ac
@ -149,6 +149,19 @@ if test "x$enable_selinux" != "xno"; then
|
|||||||
fi
|
fi
|
||||||
AM_CONDITIONAL(HAVE_SELINUX, [test "$have_selinux" = "yes"])
|
AM_CONDITIONAL(HAVE_SELINUX, [test "$have_selinux" = "yes"])
|
||||||
|
|
||||||
|
have_xz=no
|
||||||
|
AC_ARG_ENABLE(xz, AS_HELP_STRING([--disable-xz], [Disable optional XZ support]))
|
||||||
|
if test "x$enable_xz" != "xno"; then
|
||||||
|
PKG_CHECK_MODULES(XZ, [ liblzma ],
|
||||||
|
[AC_DEFINE(HAVE_XZ, 1, [Define if XZ is available]) have_xz=yes], have_xz=no)
|
||||||
|
AC_SUBST(XZ_CFLAGS)
|
||||||
|
AC_SUBST(XZ_LIBS)
|
||||||
|
if test "x$have_xz" = xno -a "x$enable_xz" = xyes; then
|
||||||
|
AC_MSG_ERROR([*** Xz support requested but libraries not found])
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(HAVE_XZ, [test "$have_xz" = "yes"])
|
||||||
|
|
||||||
AC_ARG_ENABLE([tcpwrap],
|
AC_ARG_ENABLE([tcpwrap],
|
||||||
AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]),
|
AS_HELP_STRING([--disable-tcpwrap],[Disable optional TCP wrappers support]),
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
@ -591,6 +604,7 @@ AC_MSG_RESULT([
|
|||||||
PAM: ${have_pam}
|
PAM: ${have_pam}
|
||||||
AUDIT: ${have_audit}
|
AUDIT: ${have_audit}
|
||||||
SELinux: ${have_selinux}
|
SELinux: ${have_selinux}
|
||||||
|
XZ: ${have_xz}
|
||||||
ACL: ${have_acl}
|
ACL: ${have_acl}
|
||||||
binfmt: ${have_binfmt}
|
binfmt: ${have_binfmt}
|
||||||
hostnamed: ${have_hostnamed}
|
hostnamed: ${have_hostnamed}
|
||||||
|
18
libsystemd-id128.pc.in
Normal file
18
libsystemd-id128.pc.in
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: systemd
|
||||||
|
Description: systemd 128 Bit ID Utility Library
|
||||||
|
URL: @PACKAGE_URL@
|
||||||
|
Version: @PACKAGE_VERSION@
|
||||||
|
Libs: -L${libdir} -lsystemd-id128
|
||||||
|
Cflags: -I${includedir}
|
19
libsystemd-journal.pc.in
Normal file
19
libsystemd-journal.pc.in
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
prefix=@prefix@
|
||||||
|
exec_prefix=@exec_prefix@
|
||||||
|
libdir=@libdir@
|
||||||
|
includedir=@includedir@
|
||||||
|
|
||||||
|
Name: systemd
|
||||||
|
Description: systemd Journal Utility Library
|
||||||
|
URL: @PACKAGE_URL@
|
||||||
|
Version: @PACKAGE_VERSION@
|
||||||
|
Requires: libsystemd-id128 = @PACKAGE_VERSION@
|
||||||
|
Libs: -L${libdir} -lsystemd-journal
|
||||||
|
Cflags: -I${includedir}
|
29
man/custom-html.xsl
Normal file
29
man/custom-html.xsl
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
|
||||||
|
|
||||||
|
<xsl:import href="http://docbook.sourceforge.net/release/xsl/current/html/docbook.xsl"/>
|
||||||
|
|
||||||
|
<!-- Switch things to UTF-8, ISO-8859-1 is soo yesteryear -->
|
||||||
|
<xsl:output method="html" encoding="UTF-8" indent="no"/>
|
||||||
|
|
||||||
|
</xsl:stylesheet>
|
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<funcsynopsis>
|
<funcsynopsis>
|
||||||
<funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
|
<funcsynopsisinfo>#include <systemd/sd-daemon.h></funcsynopsisinfo>
|
||||||
</funcsynopsis>
|
</funcsynopsis>
|
||||||
|
|
||||||
<cmdsynopsis>
|
<cmdsynopsis>
|
||||||
|
146
man/sd-login.xml
Normal file
146
man/sd-login.xml
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2010 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refentry id="sd-login">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>sd-login</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<contrib>Developer</contrib>
|
||||||
|
<firstname>Lennart</firstname>
|
||||||
|
<surname>Poettering</surname>
|
||||||
|
<email>lennart@poettering.net</email>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>sd-login</refentrytitle>
|
||||||
|
<manvolnum>7</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>sd-login</refname>
|
||||||
|
<refpurpose>APIs for
|
||||||
|
tracking logins</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcsynopsisinfo>#include <systemd/sd-login.h></funcsynopsisinfo>
|
||||||
|
</funcsynopsis>
|
||||||
|
|
||||||
|
<cmdsynopsis>
|
||||||
|
<command>pkg-config --cflags --libs libsystemd-login</command>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><filename>sd-login.h</filename> provides APIs to
|
||||||
|
introspect and monitor seat, login session and user
|
||||||
|
status information on the local system. </para>
|
||||||
|
|
||||||
|
<para>See <ulink
|
||||||
|
url="http://www.freedesktop.org/wiki/Software/systemd/multiseat">Multi-Seat
|
||||||
|
on Linux</ulink> for an introduction into multi-seat
|
||||||
|
support on Linux, the background for this set of APIs.</para>
|
||||||
|
|
||||||
|
<para>Note that these APIs only allow purely passive access
|
||||||
|
and monitoring of seats, sessions and users. To
|
||||||
|
actively make changes to the seat configuration,
|
||||||
|
terminate login sessions, or switch session on a seat
|
||||||
|
you need to utilize the D-Bus API of
|
||||||
|
systemd-logind, instead.</para>
|
||||||
|
|
||||||
|
<para>These functions synchronously access data in
|
||||||
|
<filename>/proc</filename>,
|
||||||
|
<filename>/sys/fs/cgroup</filename> and
|
||||||
|
<filename>/run</filename>. All of these are virtual
|
||||||
|
file systems, hence the runtime cost of the accesses
|
||||||
|
is relatively cheap.</para>
|
||||||
|
|
||||||
|
<para>It is possible (and often a very good choice) to
|
||||||
|
mix calls to the synchronous interface of
|
||||||
|
<filename>sd-login.h</filename> with the asynchronous
|
||||||
|
D-Bus interface of systemd-logind. However, if this is
|
||||||
|
done you need to think a bit about possible races
|
||||||
|
since the stream of events from D-Bus and from
|
||||||
|
<filename>sd-login.h</filename> interfaces such as the
|
||||||
|
login monitor are asynchronous and not ordered against
|
||||||
|
each other.</para>
|
||||||
|
|
||||||
|
<para>If the functions return string arrays, these are
|
||||||
|
generally NULL terminated and need to be freed by the
|
||||||
|
caller with the libc
|
||||||
|
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
call after use, including the strings referenced
|
||||||
|
therein. Similar, individual strings returned need to
|
||||||
|
be freed, as well.</para>
|
||||||
|
|
||||||
|
<para>As a special exception, instead of an empty
|
||||||
|
string array NULL may be returned, which should be
|
||||||
|
treated equivalent to an empty string array.</para>
|
||||||
|
|
||||||
|
<para>See
|
||||||
|
<citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_uid_get_state</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_seat_get_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
for more information about the functions
|
||||||
|
implemented.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>These APIs are implemented as shared library,
|
||||||
|
which can be compiled and linked to with the
|
||||||
|
<literal>libsystemd-login</literal>
|
||||||
|
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
file.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_uid_get_state</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_seat_get_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_login_monitor_new</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-daemon</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<funcsynopsis>
|
<funcsynopsis>
|
||||||
<funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
|
<funcsynopsisinfo>#include <systemd/sd-daemon.h></funcsynopsisinfo>
|
||||||
|
|
||||||
<funcprototype>
|
<funcprototype>
|
||||||
<funcdef>int <function>sd_booted</function></funcdef>
|
<funcdef>int <function>sd_booted</function></funcdef>
|
||||||
|
127
man/sd_get_seats.xml
Normal file
127
man/sd_get_seats.xml
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2010 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refentry id="sd_get_seats">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>sd_get_seats</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<contrib>Developer</contrib>
|
||||||
|
<firstname>Lennart</firstname>
|
||||||
|
<surname>Poettering</surname>
|
||||||
|
<email>lennart@poettering.net</email>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>sd_get_seats</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>sd_get_seats</refname>
|
||||||
|
<refname>sd_get_sessions</refname>
|
||||||
|
<refname>sd_get_uids</refname>
|
||||||
|
<refpurpose>Determine available seats, sessions and logged in users</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcsynopsisinfo>#include <systemd/sd-login.h></funcsynopsisinfo>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_get_seats</function></funcdef>
|
||||||
|
<paramdef>char*** <parameter>seats</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_get_sessions</function></funcdef>
|
||||||
|
<paramdef>char*** <parameter>sessions</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_get_uids</function></funcdef>
|
||||||
|
<paramdef>char*** <parameter>sessions</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><function>sd_get_seats()</function> may be used
|
||||||
|
to determine all currently available local
|
||||||
|
seats. Returns a NULL terminated array of seat
|
||||||
|
identifiers. The returned array and all strings it
|
||||||
|
references need to be freed with the libc
|
||||||
|
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
call after use. Note that instead of an empty array
|
||||||
|
NULL may be returned and should be considered
|
||||||
|
equivalent to an empty array.</para>
|
||||||
|
|
||||||
|
<para>Similar, <function>sd_get_sessions()</function> may
|
||||||
|
be used to determine all current login sessions.</para>
|
||||||
|
|
||||||
|
<para>Similar, <function>sd_get_uids()</function> may
|
||||||
|
be used to determine all Unix users who currently have login sessions.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>On success <function>sd_get_seats()</function>,
|
||||||
|
<function>sd_get_sessions()</function> and
|
||||||
|
<function>sd_get_uids()</function> return the number
|
||||||
|
of entries in the arrays. On failure, these calls
|
||||||
|
return a negative errno-style error code.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>The <function>sd_get_seats()</function>,
|
||||||
|
<function>sd_get_sessions()</function> and
|
||||||
|
<function>sd_get_uids()</function> interfaces
|
||||||
|
are available as shared library, which can be compiled
|
||||||
|
and linked to with the
|
||||||
|
<literal>libsystemd-login</literal>
|
||||||
|
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
file.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
@ -53,7 +53,7 @@
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<funcsynopsis>
|
<funcsynopsis>
|
||||||
<funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
|
<funcsynopsisinfo>#include <systemd/sd-daemon.h></funcsynopsisinfo>
|
||||||
|
|
||||||
<funcprototype>
|
<funcprototype>
|
||||||
<funcdef>int <function>sd_is_fifo</function></funcdef>
|
<funcdef>int <function>sd_is_fifo</function></funcdef>
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<funcsynopsis>
|
<funcsynopsis>
|
||||||
<funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
|
<funcsynopsisinfo>#include <systemd/sd-daemon.h></funcsynopsisinfo>
|
||||||
|
|
||||||
<funcsynopsisinfo>#define SD_LISTEN_FDS_START 3</funcsynopsisinfo>
|
<funcsynopsisinfo>#define SD_LISTEN_FDS_START 3</funcsynopsisinfo>
|
||||||
|
|
||||||
|
172
man/sd_login_monitor_new.xml
Normal file
172
man/sd_login_monitor_new.xml
Normal file
@ -0,0 +1,172 @@
|
|||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2010 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refentry id="sd_login_monitor_new">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>sd_login_monitor_new</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<contrib>Developer</contrib>
|
||||||
|
<firstname>Lennart</firstname>
|
||||||
|
<surname>Poettering</surname>
|
||||||
|
<email>lennart@poettering.net</email>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>sd_login_monitor_new</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>sd_login_monitor_new</refname>
|
||||||
|
<refname>sd_login_monitor_unref</refname>
|
||||||
|
<refname>sd_login_monitor_flush</refname>
|
||||||
|
<refname>sd_login_monitor_get_fd</refname>
|
||||||
|
<refpurpose>Monitor login sessions, seats and users</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcsynopsisinfo>#include <systemd/sd-login.h></funcsynopsisinfo>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_login_monitor_new</function></funcdef>
|
||||||
|
<paramdef>const char* <parameter>category</parameter></paramdef>
|
||||||
|
<paramdef>sd_login_monitor** <parameter>ret</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>sd_login_monitor* <function>sd_login_monitor_unref</function></funcdef>
|
||||||
|
<paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_login_monitor_flush</function></funcdef>
|
||||||
|
<paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_login_monitor_get_fd</function></funcdef>
|
||||||
|
<paramdef>sd_login_monitor* <parameter>m</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><function>sd_login_monitor_new()</function> may
|
||||||
|
be used to monitor login session, users and seats. Via
|
||||||
|
a monitor object a file descriptor can be integrated
|
||||||
|
into an application defined event loop which is woken
|
||||||
|
up each time a user logs in, logs out or a seat is
|
||||||
|
added or removed, or a session, user, or seat changes
|
||||||
|
state otherwise. The first parameter takes a string
|
||||||
|
which can be either <literal>seat</literal> (to get
|
||||||
|
only notifications about seats being added, removed or
|
||||||
|
changed), <literal>session</literal> (to get only
|
||||||
|
notifications about sessions being created or removed
|
||||||
|
or changed) or <literal>uid</literal> (to get only
|
||||||
|
notifications when a user changes state in respect to
|
||||||
|
logins). If notifications shall be generated in all
|
||||||
|
these conditions, NULL may be passed. Note that in
|
||||||
|
future additional categories may be defined. The
|
||||||
|
second parameter returns a monitor object and needs to
|
||||||
|
be freed with the
|
||||||
|
<function>sd_login_monitor_unref()</function> call
|
||||||
|
after use.</para>
|
||||||
|
|
||||||
|
<para><function>sd_login_monitor_unref()</function>
|
||||||
|
may be used to destroy a monitor object. Note that
|
||||||
|
this will invalidate any file descriptor returned by
|
||||||
|
<function>sd_login_monitor_get_fd()</function>.</para>
|
||||||
|
|
||||||
|
<para><function>sd_login_monitor_flush()</function>
|
||||||
|
may be used to reset the wakeup state of the monitor
|
||||||
|
object. Whenever an event causes the monitor to wake
|
||||||
|
up the event loop via the file descriptor this
|
||||||
|
function needs to be called to reset the wake-up
|
||||||
|
state. If this call is not invoked the file descriptor
|
||||||
|
will immediately wake up the event loop again.</para>
|
||||||
|
|
||||||
|
<para><function>sd_login_monitor_get_fd()</function>
|
||||||
|
may be used to retrieve the file descriptor of the
|
||||||
|
monitor object that may be integrated in an
|
||||||
|
application defined event loop, based around
|
||||||
|
<citerefentry><refentrytitle>poll</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
|
or a similar interface. The application should include
|
||||||
|
the returned file descriptor as wake up source for
|
||||||
|
POLLIN events. Whenever a wake-up is triggered the
|
||||||
|
file descriptor needs to be reset via
|
||||||
|
<function>sd_login_monitor_flush()</function>. An
|
||||||
|
application needs to reread the login state with a
|
||||||
|
function like
|
||||||
|
<citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
or similar to determine what changed.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>On success
|
||||||
|
<function>sd_login_monitor_new()</function> and
|
||||||
|
<function>sd_login_monitor_flush()</function> return 0
|
||||||
|
or a positive integer. On success
|
||||||
|
<function>sd_login_monitor_get_fd()</function> returns
|
||||||
|
a Unix file descriptor. On failure, these calls return
|
||||||
|
a negative errno-style error code.</para>
|
||||||
|
|
||||||
|
<para><function>sd_login_monitor_unref()</function>
|
||||||
|
always returns NULL.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>The <function>sd_login_monitor_new()</function>,
|
||||||
|
<function>sd_login_monitor_unref()</function>, <function>sd_login_monitor_flush()</function> and
|
||||||
|
<function>sd_login_monitor_get_fd()</function> interfaces
|
||||||
|
are available as shared library, which can be compiled
|
||||||
|
and linked to with the
|
||||||
|
<literal>libsystemd-login</literal>
|
||||||
|
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
file.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_get_seats</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
@ -50,7 +50,7 @@
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<funcsynopsis>
|
<funcsynopsis>
|
||||||
<funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
|
<funcsynopsisinfo>#include <systemd/sd-daemon.h></funcsynopsisinfo>
|
||||||
|
|
||||||
<funcprototype>
|
<funcprototype>
|
||||||
<funcdef>int <function>sd_notify</function></funcdef>
|
<funcdef>int <function>sd_notify</function></funcdef>
|
||||||
|
135
man/sd_pid_get_session.xml
Normal file
135
man/sd_pid_get_session.xml
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2010 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refentry id="sd_pid_get_session">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>sd_pid_get_session</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<contrib>Developer</contrib>
|
||||||
|
<firstname>Lennart</firstname>
|
||||||
|
<surname>Poettering</surname>
|
||||||
|
<email>lennart@poettering.net</email>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>sd_pid_get_session</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>sd_pid_get_session</refname>
|
||||||
|
<refname>sd_pid_get_owner_uid</refname>
|
||||||
|
<refpurpose>Determine session or owner of a session of a specific PID</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcsynopsisinfo>#include <systemd/sd-login.h></funcsynopsisinfo>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_pid_get_session</function></funcdef>
|
||||||
|
<paramdef>pid_t <parameter>pid</parameter></paramdef>
|
||||||
|
<paramdef>char** <parameter>session</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_pid_get_owner_uid</function></funcdef>
|
||||||
|
<paramdef>pid_t <parameter>pid</parameter></paramdef>
|
||||||
|
<paramdef>uid_t* <parameter>uid</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><function>sd_pid_get_session()</function> may be
|
||||||
|
used to determine the login session identifier of a
|
||||||
|
process identified by the specified process
|
||||||
|
identifier. The session identifier is a short string,
|
||||||
|
suitable for usage in file system paths. Note that not
|
||||||
|
all processes are part of a login session (e.g. system
|
||||||
|
service processes and user processes that are shared
|
||||||
|
between multiple sessions of the same user). For
|
||||||
|
processes not being part of a login session this
|
||||||
|
function will fail. The returned string needs to be
|
||||||
|
freed with the libc
|
||||||
|
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
call after use.</para>
|
||||||
|
|
||||||
|
<para><function>sd_pid_get_owner_uid()</function> may
|
||||||
|
be used to determine the Unix user identifier of the
|
||||||
|
owner of the session of a process identified the
|
||||||
|
specified PID. Note that this function will succeed
|
||||||
|
for user processes which are shared between multiple
|
||||||
|
login sessions of the same user, where
|
||||||
|
<function>sd_pid_get_session()</function> will
|
||||||
|
fail. For processes not being part of a login session
|
||||||
|
and not being a shared process of a user this function
|
||||||
|
will fail.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>On success these calls return 0 or a positive
|
||||||
|
integer. On failure, these calls return a negative
|
||||||
|
errno-style error code.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>The <function>sd_pid_get_session()</function>
|
||||||
|
and <function>sd_pid_get_owner_uid()</function>
|
||||||
|
interfaces are available as shared library, which can
|
||||||
|
be compiled and linked to with the
|
||||||
|
<literal>libsystemd-login</literal>
|
||||||
|
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
file.</para>
|
||||||
|
|
||||||
|
<para>Note that the login session identifier as
|
||||||
|
returned by <function>sd_pid_get_session()</function>
|
||||||
|
is completely unrelated to the process session
|
||||||
|
identifier as returned by
|
||||||
|
<citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_session_is_active</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>getsid</refentrytitle><manvolnum>2</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
@ -49,7 +49,7 @@
|
|||||||
|
|
||||||
<refsynopsisdiv>
|
<refsynopsisdiv>
|
||||||
<funcsynopsis>
|
<funcsynopsis>
|
||||||
<funcsynopsisinfo>#include "sd-daemon.h"</funcsynopsisinfo>
|
<funcsynopsisinfo>#include "sd-readahead.h"</funcsynopsisinfo>
|
||||||
|
|
||||||
<funcprototype>
|
<funcprototype>
|
||||||
<funcdef>int <function>sd_readahead</function></funcdef>
|
<funcdef>int <function>sd_readahead</function></funcdef>
|
||||||
@ -134,23 +134,17 @@
|
|||||||
url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.h"/></para>
|
url="http://cgit.freedesktop.org/systemd/tree/src/sd-readahead.h"/></para>
|
||||||
|
|
||||||
<para><function>sd_readahead()</function> is
|
<para><function>sd_readahead()</function> is
|
||||||
implemented in the reference implementation's
|
implemented in the reference implementation's drop-in
|
||||||
<filename>sd-readahead.c</filename> and
|
<filename>sd-readahead.c</filename> and
|
||||||
<filename>sd-readahead.h</filename> files. These
|
<filename>sd-readahead.h</filename> files. It is
|
||||||
interfaces are available as shared library, which can
|
recommended that applications consuming this API copy
|
||||||
be compiled and linked to with the
|
the implementation into their source tree. For more
|
||||||
<literal>libsystemd-daemon</literal>
|
details about the reference implementation see
|
||||||
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
<citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry></para>
|
||||||
file. Alternatively, applications consuming this API
|
|
||||||
may copy the implementation into their source
|
|
||||||
tree. For more details about the reference
|
|
||||||
implementation see
|
|
||||||
<citerefentry><refentrytitle>sd-readahead</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
|
|
||||||
|
|
||||||
<para>If the reference implementation is used as
|
<para>If -DDISABLE_SYSTEMD is set during compilation
|
||||||
drop-in files and -DDISABLE_SYSTEMD is set during
|
this function will always return 0 and otherwise
|
||||||
compilation this function will always return 0 and
|
become a NOP.</para>
|
||||||
otherwise become a NOP.</para>
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
152
man/sd_seat_get_active.xml
Normal file
152
man/sd_seat_get_active.xml
Normal file
@ -0,0 +1,152 @@
|
|||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2010 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refentry id="sd_seat_get_active">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>sd_seat_get_active</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<contrib>Developer</contrib>
|
||||||
|
<firstname>Lennart</firstname>
|
||||||
|
<surname>Poettering</surname>
|
||||||
|
<email>lennart@poettering.net</email>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>sd_seat_get_active</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>sd_seat_get_active</refname>
|
||||||
|
<refname>sd_seat_get_sessions</refname>
|
||||||
|
<refname>sd_seat_can_multi_session</refname>
|
||||||
|
<refpurpose>Determine state of a specific seat</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcsynopsisinfo>#include <systemd/sd-login.h></funcsynopsisinfo>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_seat_get_active</function></funcdef>
|
||||||
|
<paramdef>const char* <parameter>seat</parameter></paramdef>
|
||||||
|
<paramdef>char** <parameter>session</parameter></paramdef>
|
||||||
|
<paramdef>uid_t* <parameter>uid</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_seat_get_sessions</function></funcdef>
|
||||||
|
<paramdef>const char* <parameter>seat</parameter></paramdef>
|
||||||
|
<paramdef>char*** <parameter>sessions</parameter></paramdef>
|
||||||
|
<paramdef>uid_t** <parameter>uid</parameter></paramdef>
|
||||||
|
<paramdef>unsigned* <parameter>n_uids</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_seat_can_multi_session</function></funcdef>
|
||||||
|
<paramdef>const char* <parameter>session</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><function>sd_seat_get_active()</function> may be
|
||||||
|
used to determine which session is currently active on
|
||||||
|
a seat, if there is any. Returns the session
|
||||||
|
identifier and the user identifier of the Unix user
|
||||||
|
the session is belonging to. Either the session or the
|
||||||
|
user identifier parameter can be be passed NULL, in
|
||||||
|
case only one of the parameters shall be queried. The
|
||||||
|
returned string needs to be freed with the libc
|
||||||
|
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
call after use.</para>
|
||||||
|
|
||||||
|
<para><function>sd_seat_get_sessions()</function> may
|
||||||
|
be used to determine all sessions on the specified
|
||||||
|
seat. Returns two arrays, one (NULL terminated) with
|
||||||
|
the session identifiers of the sessions and one with
|
||||||
|
the user identifiers of the Unix users the sessions
|
||||||
|
belong to. An additional parameter may be used to
|
||||||
|
return the number of entries in the latter array. The
|
||||||
|
two arrays and the latter parameter may be passed as
|
||||||
|
NULL in case these values need not to be
|
||||||
|
determined. The arrays and the strings referenced by
|
||||||
|
them need to be freed with the libc
|
||||||
|
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
call after use. Note that instead of an empty array
|
||||||
|
NULL may be returned and should be considered
|
||||||
|
equivalent to an empty array.</para>
|
||||||
|
|
||||||
|
<para><function>sd_seat_can_multi_session()</function>
|
||||||
|
may be used to determine whether a specific seat is
|
||||||
|
capable of multi-session, i.e. allows multiple login
|
||||||
|
sessions in parallel (whith only one being active at a
|
||||||
|
time).</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para> On success
|
||||||
|
<function>sd_seat_get_active()</function> return
|
||||||
|
return 0 or a positive integer. On success
|
||||||
|
<function>sd_seat_get_sessions()</function> returns
|
||||||
|
the number of entries in the session identifier
|
||||||
|
array. If the test succeeds
|
||||||
|
<function>sd_seat_can_multi_session</function> returns
|
||||||
|
a positive integer, if it fails 0. On failure, these
|
||||||
|
calls return a negative errno-style error code.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>The <function>sd_seat_get_active()</function>,
|
||||||
|
<function>sd_seat_get_sessions()</function>, and
|
||||||
|
<function>sd_seat_can_multi_session()</function> interfaces
|
||||||
|
are available as shared library, which can be compiled
|
||||||
|
and linked to with the
|
||||||
|
<literal>libsystemd-login</literal>
|
||||||
|
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
file.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_session_get_seat</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
134
man/sd_session_is_active.xml
Normal file
134
man/sd_session_is_active.xml
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2010 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refentry id="sd_session_is_active">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>sd_session_is_active</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<contrib>Developer</contrib>
|
||||||
|
<firstname>Lennart</firstname>
|
||||||
|
<surname>Poettering</surname>
|
||||||
|
<email>lennart@poettering.net</email>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>sd_session_is_active</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>sd_session_is_active</refname>
|
||||||
|
<refname>sd_session_get_uid</refname>
|
||||||
|
<refname>sd_session_get_seat</refname>
|
||||||
|
<refpurpose>Determine state of a specific session</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcsynopsisinfo>#include <systemd/sd-login.h></funcsynopsisinfo>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_session_is_active</function></funcdef>
|
||||||
|
<paramdef>const char* <parameter>session</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_session_get_uid</function></funcdef>
|
||||||
|
<paramdef>const char* <parameter>session</parameter></paramdef>
|
||||||
|
<paramdef>uid_t* <parameter>uid</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_session_get_seat</function></funcdef>
|
||||||
|
<paramdef>const char* <parameter>session</parameter></paramdef>
|
||||||
|
<paramdef>char** <parameter>seat</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><function>sd_session_is_active()</function> may
|
||||||
|
be used to determine whether the session identified by
|
||||||
|
the specified session identifier is currently active
|
||||||
|
(i.e. currently in the foreground and available for
|
||||||
|
user input) or not.</para>
|
||||||
|
|
||||||
|
<para><function>sd_session_get_uid()</function> may be
|
||||||
|
used to determine the user identifier of the Unix user the session
|
||||||
|
identified by the specified session identifier belongs
|
||||||
|
to.</para>
|
||||||
|
|
||||||
|
<para><function>sd_session_get_seat()</function> may
|
||||||
|
be used to determine the seat identifier of the seat
|
||||||
|
the session identified by the specified session
|
||||||
|
identifier belongs to. Note that not all sessions are
|
||||||
|
attached to a seat, this call will fail for them. The
|
||||||
|
returned string needs to be freed with the libc
|
||||||
|
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
call after use.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>If the test succeeds
|
||||||
|
<function>sd_session_is_active()</function> returns a
|
||||||
|
positive integer, if it fails 0. On success
|
||||||
|
<function>sd_session_get_uid()</function> and
|
||||||
|
<function>sd_session_get_seat()</function> return 0 or
|
||||||
|
a positive integer. On failure, these calls return a
|
||||||
|
negative errno-style error code.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>The <function>sd_session_is_active()</function>,
|
||||||
|
<function>sd_session_get_uid()</function>, and
|
||||||
|
<function>sd_session_get_seat()</function> interfaces
|
||||||
|
are available as shared library, which can be compiled
|
||||||
|
and linked to with the
|
||||||
|
<literal>libsystemd-login</literal>
|
||||||
|
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
file.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_pid_get_session</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
185
man/sd_uid_get_state.xml
Normal file
185
man/sd_uid_get_state.xml
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||||
|
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
|
||||||
|
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2010 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<refentry id="sd_uid_get_state">
|
||||||
|
|
||||||
|
<refentryinfo>
|
||||||
|
<title>sd_uid_get_state</title>
|
||||||
|
<productname>systemd</productname>
|
||||||
|
|
||||||
|
<authorgroup>
|
||||||
|
<author>
|
||||||
|
<contrib>Developer</contrib>
|
||||||
|
<firstname>Lennart</firstname>
|
||||||
|
<surname>Poettering</surname>
|
||||||
|
<email>lennart@poettering.net</email>
|
||||||
|
</author>
|
||||||
|
</authorgroup>
|
||||||
|
</refentryinfo>
|
||||||
|
|
||||||
|
<refmeta>
|
||||||
|
<refentrytitle>sd_uid_get_state</refentrytitle>
|
||||||
|
<manvolnum>3</manvolnum>
|
||||||
|
</refmeta>
|
||||||
|
|
||||||
|
<refnamediv>
|
||||||
|
<refname>sd_uid_get_state</refname>
|
||||||
|
<refname>sd_uid_is_on_seat</refname>
|
||||||
|
<refname>sd_uid_get_sessions</refname>
|
||||||
|
<refname>sd_uid_get_seats</refname>
|
||||||
|
<refpurpose>Determine login state of a specific Unix user ID</refpurpose>
|
||||||
|
</refnamediv>
|
||||||
|
|
||||||
|
<refsynopsisdiv>
|
||||||
|
<funcsynopsis>
|
||||||
|
<funcsynopsisinfo>#include <systemd/sd-login.h></funcsynopsisinfo>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_uid_get_state</function></funcdef>
|
||||||
|
<paramdef>uid_t <parameter>pid</parameter></paramdef>
|
||||||
|
<paramdef>char** <parameter>state</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_uid_is_on_seat</function></funcdef>
|
||||||
|
<paramdef>uid_t <parameter>pid</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>require_active</parameter></paramdef>
|
||||||
|
<paramdef>const char* <parameter>seat</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_uid_get_sessions</function></funcdef>
|
||||||
|
<paramdef>uid_t <parameter>pid</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>require_active</parameter></paramdef>
|
||||||
|
<paramdef>char*** <parameter>sessions</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
|
||||||
|
<funcprototype>
|
||||||
|
<funcdef>int <function>sd_uid_get_seats</function></funcdef>
|
||||||
|
<paramdef>uid_t <parameter>pid</parameter></paramdef>
|
||||||
|
<paramdef>int <parameter>require_active</parameter></paramdef>
|
||||||
|
<paramdef>char*** <parameter>seats</parameter></paramdef>
|
||||||
|
</funcprototype>
|
||||||
|
</funcsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Description</title>
|
||||||
|
|
||||||
|
<para><function>sd_uid_get_state()</function> may be
|
||||||
|
used to determine the login state of a specific Unix
|
||||||
|
user identifier. The following states are currently
|
||||||
|
known: <literal>offline</literal> (user not logged in
|
||||||
|
at all), <literal>lingering</literal> (user not logged
|
||||||
|
in, but some user services running),
|
||||||
|
<literal>online</literal> (user logged in, but not
|
||||||
|
active), <literal>active</literal> (user logged in on
|
||||||
|
an active seat). In the future additional states might
|
||||||
|
be defined, client code should be written to be robust
|
||||||
|
in regards to additional state strings being
|
||||||
|
returned. The returned string needs to be freed with
|
||||||
|
the libc
|
||||||
|
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
call after use.</para>
|
||||||
|
|
||||||
|
<para><function>sd_uid_is_on_seat()</function> may be
|
||||||
|
used to determine whether a specific user is logged in
|
||||||
|
or active on a specific seat. Accepts a Unix user
|
||||||
|
identifier and a seat identifier string as
|
||||||
|
parameters. The <parameter>require_active</parameter>
|
||||||
|
parameter is a boolean. If non-zero (true) this
|
||||||
|
function will test if the user is active (i.e. has a
|
||||||
|
session that is in the foreground and accepting user
|
||||||
|
input) on the specified seat, otherwise (false) only
|
||||||
|
if the user is logged in (and possibly inactive) on
|
||||||
|
the specified seat.</para>
|
||||||
|
|
||||||
|
<para><function>sd_uid_get_sessions()</function> may
|
||||||
|
be used to determine the current sessions of the
|
||||||
|
specified user. Acceptes a Unix user identifier as
|
||||||
|
parameter. The <parameter>require_active</parameter>
|
||||||
|
boolean parameter controls whether the returned list
|
||||||
|
shall consist of only those sessions where the user is
|
||||||
|
currently active (true) or where the user is currently
|
||||||
|
logged in at all, possibly inactive (false). The call
|
||||||
|
returns a NULL terminated string array of session
|
||||||
|
identifiers in <parameter>sessions</parameter> which
|
||||||
|
needs to be freed by the caller with the libc
|
||||||
|
<citerefentry><refentrytitle>free</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
call after use, including all the strings
|
||||||
|
referenced. If the string array parameter is passed as
|
||||||
|
NULL the array will not be filled in, but the return
|
||||||
|
code still indicates the number of current
|
||||||
|
sessions. Note that instead of an empty array NULL may
|
||||||
|
be returned and should be considered equivalent to an
|
||||||
|
empty array.</para>
|
||||||
|
|
||||||
|
<para>Similar, <function>sd_uid_get_seats()</function>
|
||||||
|
may be used to determine the list of seats on which
|
||||||
|
the user currently has sessions. Similar semantics
|
||||||
|
apply, however note that the user may have
|
||||||
|
multiple sessions on the same seat as well as sessions
|
||||||
|
with no attached seat and hence the number of entries
|
||||||
|
in the returned array may differ from the one returned
|
||||||
|
by <function>sd_uid_get_sessions()</function>.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Return Value</title>
|
||||||
|
|
||||||
|
<para>On success
|
||||||
|
<function>sd_uid_get_state()</function> returns 0 or a
|
||||||
|
positive integer. If the test succeeds
|
||||||
|
<function>sd_uid_is_on_seat()</function> returns a
|
||||||
|
positive integer, if it fails
|
||||||
|
0. <function>sd_uid_get_sessions()</function> and
|
||||||
|
<function>sd_uid_get_seats()</function> return the
|
||||||
|
number of entries in the returned arrays. On failure,
|
||||||
|
these calls return a negative errno-style error
|
||||||
|
code.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>Notes</title>
|
||||||
|
|
||||||
|
<para>The <function>sd_uid_get_state()</function>,
|
||||||
|
<function>sd_uid_is_on_seat()</function>,
|
||||||
|
<function>sd_uid_get_sessions()</function>, and
|
||||||
|
<function>sd_uid_get_seats()</function> interfaces are
|
||||||
|
available as shared library, which can be compiled and
|
||||||
|
linked to with the <literal>libsystemd-login</literal>
|
||||||
|
<citerefentry><refentrytitle>pkg-config</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||||
|
file.</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
<refsect1>
|
||||||
|
<title>See Also</title>
|
||||||
|
|
||||||
|
<para>
|
||||||
|
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd-login</refentrytitle><manvolnum>7</manvolnum></citerefentry>,
|
||||||
|
<citerefentry><refentrytitle>sd_pid_get_owner_uid</refentrytitle><manvolnum>3</manvolnum></citerefentry>
|
||||||
|
</para>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
</refentry>
|
1
po/.gitignore
vendored
1
po/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
POTFILES
|
POTFILES
|
||||||
Makefile.in.in
|
Makefile.in.in
|
||||||
.intltool-merge-cache
|
.intltool-merge-cache
|
||||||
|
Makefile
|
||||||
|
@ -44,7 +44,7 @@ SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", ENV{ID_USB_INTERFACES}=="*:0701??:
|
|||||||
|
|
||||||
# Apply sysctl variables to network devices (and only to those) as they appear.
|
# Apply sysctl variables to network devices (and only to those) as they appear.
|
||||||
|
|
||||||
SUBSYSTEM=="net", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name"
|
SUBSYSTEM=="net", KERNEL!="lo", RUN+="@rootlibexecdir@/systemd-sysctl --prefix=/proc/sys/net/ipv4/conf/$name --prefix=/proc/sys/net/ipv4/neigh/$name --prefix=/proc/sys/net/ipv6/conf/$name --prefix=/proc/sys/net/ipv6/neigh/$name"
|
||||||
|
|
||||||
# Asynchronously mount file systems implemented by these modules as
|
# Asynchronously mount file systems implemented by these modules as
|
||||||
# soon as they are loaded.
|
# soon as they are loaded.
|
||||||
|
68
src/acl-util.c
Normal file
68
src/acl-util.c
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <sys/acl.h>
|
||||||
|
#include <acl/libacl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "acl-util.h"
|
||||||
|
|
||||||
|
int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry) {
|
||||||
|
acl_entry_t i;
|
||||||
|
int found;
|
||||||
|
|
||||||
|
assert(acl);
|
||||||
|
assert(entry);
|
||||||
|
|
||||||
|
for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
|
||||||
|
found > 0;
|
||||||
|
found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
|
||||||
|
|
||||||
|
acl_tag_t tag;
|
||||||
|
uid_t *u;
|
||||||
|
bool b;
|
||||||
|
|
||||||
|
if (acl_get_tag_type(i, &tag) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (tag != ACL_USER)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
u = acl_get_qualifier(i);
|
||||||
|
if (!u)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
b = *u == uid;
|
||||||
|
acl_free(u);
|
||||||
|
|
||||||
|
if (b) {
|
||||||
|
*entry = i;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
27
src/acl-util.h
Normal file
27
src/acl-util.h
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef fooaclutilhfoo
|
||||||
|
#define fooaclutilhfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
int acl_find_uid(acl_t acl, uid_t uid, acl_entry_t *entry);
|
||||||
|
|
||||||
|
#endif
|
@ -770,7 +770,7 @@ static void automount_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
|
|||||||
if (packet.v5_packet.pid > 0) {
|
if (packet.v5_packet.pid > 0) {
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
|
|
||||||
get_process_name(packet.v5_packet.pid, &p);
|
get_process_comm(packet.v5_packet.pid, &p);
|
||||||
log_debug("Got direct mount request for %s, triggered by %lu (%s)", packet.v5_packet.name, (unsigned long) packet.v5_packet.pid, strna(p));
|
log_debug("Got direct mount request for %s, triggered by %lu (%s)", packet.v5_packet.name, (unsigned long) packet.v5_packet.pid, strna(p));
|
||||||
free(p);
|
free(p);
|
||||||
|
|
||||||
|
@ -133,7 +133,7 @@ static int show_cgroup_one_by_path(const char *path, const char *prefix, unsigne
|
|||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
char *t = NULL;
|
char *t = NULL;
|
||||||
|
|
||||||
get_process_cmdline(pids[i], n_columns, &t);
|
get_process_cmdline(pids[i], n_columns, true, &t);
|
||||||
|
|
||||||
printf("%s%s %*lu %s\n",
|
printf("%s%s %*lu %s\n",
|
||||||
prefix,
|
prefix,
|
||||||
|
@ -558,6 +558,17 @@ void* hashmap_first(Hashmap *h) {
|
|||||||
return h->iterate_list_head->value;
|
return h->iterate_list_head->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void* hashmap_first_key(Hashmap *h) {
|
||||||
|
|
||||||
|
if (!h)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
if (!h->iterate_list_head)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
return (void*) h->iterate_list_head->key;
|
||||||
|
}
|
||||||
|
|
||||||
void* hashmap_last(Hashmap *h) {
|
void* hashmap_last(Hashmap *h) {
|
||||||
|
|
||||||
if (!h)
|
if (!h)
|
||||||
|
@ -74,6 +74,7 @@ void hashmap_clear(Hashmap *h);
|
|||||||
void *hashmap_steal_first(Hashmap *h);
|
void *hashmap_steal_first(Hashmap *h);
|
||||||
void *hashmap_steal_first_key(Hashmap *h);
|
void *hashmap_steal_first_key(Hashmap *h);
|
||||||
void* hashmap_first(Hashmap *h);
|
void* hashmap_first(Hashmap *h);
|
||||||
|
void* hashmap_first_key(Hashmap *h);
|
||||||
void* hashmap_last(Hashmap *h);
|
void* hashmap_last(Hashmap *h);
|
||||||
|
|
||||||
char **hashmap_get_strv(Hashmap *h);
|
char **hashmap_get_strv(Hashmap *h);
|
||||||
|
1
src/journal/Makefile
Symbolic link
1
src/journal/Makefile
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../Makefile
|
208
src/journal/compress.c
Normal file
208
src/journal/compress.c
Normal file
@ -0,0 +1,208 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <lzma.h>
|
||||||
|
|
||||||
|
#include "compress.h"
|
||||||
|
|
||||||
|
bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size) {
|
||||||
|
lzma_stream s = LZMA_STREAM_INIT;
|
||||||
|
lzma_ret ret;
|
||||||
|
bool b = false;
|
||||||
|
|
||||||
|
assert(src);
|
||||||
|
assert(src_size > 0);
|
||||||
|
assert(dst);
|
||||||
|
assert(dst_size);
|
||||||
|
|
||||||
|
/* Returns false if we couldn't compress the data or the
|
||||||
|
* compressed result is longer than the original */
|
||||||
|
|
||||||
|
ret = lzma_easy_encoder(&s, LZMA_PRESET_DEFAULT, LZMA_CHECK_NONE);
|
||||||
|
if (ret != LZMA_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
s.next_in = src;
|
||||||
|
s.avail_in = src_size;
|
||||||
|
s.next_out = dst;
|
||||||
|
s.avail_out = src_size;
|
||||||
|
|
||||||
|
/* Does it fit? */
|
||||||
|
if (lzma_code(&s, LZMA_FINISH) != LZMA_STREAM_END)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
/* Is it actually shorter? */
|
||||||
|
if (s.avail_out == 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
*dst_size = src_size - s.avail_out;
|
||||||
|
b = true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
lzma_end(&s);
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool uncompress_blob(const void *src, uint64_t src_size,
|
||||||
|
void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size) {
|
||||||
|
|
||||||
|
lzma_stream s = LZMA_STREAM_INIT;
|
||||||
|
lzma_ret ret;
|
||||||
|
bool b = false;
|
||||||
|
|
||||||
|
assert(src);
|
||||||
|
assert(src_size > 0);
|
||||||
|
assert(dst);
|
||||||
|
assert(dst_alloc_size);
|
||||||
|
assert(dst_size);
|
||||||
|
assert(*dst_alloc_size == 0 || *dst);
|
||||||
|
|
||||||
|
ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
|
||||||
|
if (ret != LZMA_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (*dst_alloc_size <= src_size) {
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
p = realloc(*dst, src_size*2);
|
||||||
|
if (!p)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*dst = p;
|
||||||
|
*dst_alloc_size = src_size*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
s.next_in = src;
|
||||||
|
s.avail_in = src_size;
|
||||||
|
|
||||||
|
s.next_out = *dst;
|
||||||
|
s.avail_out = *dst_alloc_size;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
ret = lzma_code(&s, LZMA_FINISH);
|
||||||
|
|
||||||
|
if (ret == LZMA_STREAM_END)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ret != LZMA_OK)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
p = realloc(*dst, *dst_alloc_size*2);
|
||||||
|
if (!p)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *dst);
|
||||||
|
s.avail_out += *dst_alloc_size;
|
||||||
|
|
||||||
|
*dst = p;
|
||||||
|
*dst_alloc_size *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst_size = *dst_alloc_size - s.avail_out;
|
||||||
|
b = true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
lzma_end(&s);
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool uncompress_startswith(const void *src, uint64_t src_size,
|
||||||
|
void **buffer, uint64_t *buffer_size,
|
||||||
|
const void *prefix, uint64_t prefix_len,
|
||||||
|
uint8_t extra) {
|
||||||
|
|
||||||
|
lzma_stream s = LZMA_STREAM_INIT;
|
||||||
|
lzma_ret ret;
|
||||||
|
bool b = false;
|
||||||
|
|
||||||
|
/* Checks whether the uncompressed blob starts with the
|
||||||
|
* mentioned prefix. The byte extra needs to follow the
|
||||||
|
* prefix */
|
||||||
|
|
||||||
|
assert(src);
|
||||||
|
assert(src_size > 0);
|
||||||
|
assert(buffer);
|
||||||
|
assert(buffer_size);
|
||||||
|
assert(prefix);
|
||||||
|
assert(*buffer_size == 0 || *buffer);
|
||||||
|
|
||||||
|
ret = lzma_stream_decoder(&s, UINT64_MAX, 0);
|
||||||
|
if (ret != LZMA_OK)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (*buffer_size <= prefix_len) {
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
p = realloc(*buffer, prefix_len*2);
|
||||||
|
if (!p)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
*buffer = p;
|
||||||
|
*buffer_size = prefix_len*2;
|
||||||
|
}
|
||||||
|
|
||||||
|
s.next_in = src;
|
||||||
|
s.avail_in = src_size;
|
||||||
|
|
||||||
|
s.next_out = *buffer;
|
||||||
|
s.avail_out = *buffer_size;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
void *p;
|
||||||
|
|
||||||
|
ret = lzma_code(&s, LZMA_FINISH);
|
||||||
|
|
||||||
|
if (ret != LZMA_STREAM_END && ret != LZMA_OK)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if ((*buffer_size - s.avail_out > prefix_len) &&
|
||||||
|
memcmp(*buffer, prefix, prefix_len) == 0 &&
|
||||||
|
((const uint8_t*) *buffer)[prefix_len] == extra)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ret == LZMA_STREAM_END)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
p = realloc(*buffer, *buffer_size*2);
|
||||||
|
if (!p)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
s.next_out = (uint8_t*) p + ((uint8_t*) s.next_out - (uint8_t*) *buffer);
|
||||||
|
s.avail_out += *buffer_size;
|
||||||
|
|
||||||
|
*buffer = p;
|
||||||
|
*buffer_size *= 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
b = true;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
lzma_end(&s);
|
||||||
|
|
||||||
|
return b;
|
||||||
|
}
|
38
src/journal/compress.h
Normal file
38
src/journal/compress.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef foocompresshfoo
|
||||||
|
#define foocompresshfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
bool compress_blob(const void *src, uint64_t src_size, void *dst, uint64_t *dst_size);
|
||||||
|
|
||||||
|
bool uncompress_blob(const void *src, uint64_t src_size,
|
||||||
|
void **dst, uint64_t *dst_alloc_size, uint64_t* dst_size);
|
||||||
|
|
||||||
|
bool uncompress_startswith(const void *src, uint64_t src_size,
|
||||||
|
void **buffer, uint64_t *buffer_size,
|
||||||
|
const void *prefix, uint64_t prefix_len,
|
||||||
|
uint8_t extra);
|
||||||
|
|
||||||
|
#endif
|
164
src/journal/journal-def.h
Normal file
164
src/journal/journal-def.h
Normal file
@ -0,0 +1,164 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef foojournaldefhfoo
|
||||||
|
#define foojournaldefhfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "macro.h"
|
||||||
|
#include "sd-id128.h"
|
||||||
|
|
||||||
|
typedef struct Header Header;
|
||||||
|
typedef struct ObjectHeader ObjectHeader;
|
||||||
|
typedef union Object Object;
|
||||||
|
typedef struct DataObject DataObject;
|
||||||
|
typedef struct FieldObject FieldObject;
|
||||||
|
typedef struct EntryObject EntryObject;
|
||||||
|
typedef struct HashTableObject HashTableObject;
|
||||||
|
typedef struct EntryArrayObject EntryArrayObject;
|
||||||
|
typedef struct EntryItem EntryItem;
|
||||||
|
typedef struct HashItem HashItem;
|
||||||
|
|
||||||
|
/* Object types */
|
||||||
|
enum {
|
||||||
|
OBJECT_UNUSED,
|
||||||
|
OBJECT_DATA,
|
||||||
|
OBJECT_FIELD,
|
||||||
|
OBJECT_ENTRY,
|
||||||
|
OBJECT_DATA_HASH_TABLE,
|
||||||
|
OBJECT_FIELD_HASH_TABLE,
|
||||||
|
OBJECT_ENTRY_ARRAY,
|
||||||
|
_OBJECT_TYPE_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Object flags */
|
||||||
|
enum {
|
||||||
|
OBJECT_COMPRESSED = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct ObjectHeader {
|
||||||
|
uint8_t type;
|
||||||
|
uint8_t flags;
|
||||||
|
uint8_t reserved[6];
|
||||||
|
uint64_t size;
|
||||||
|
uint8_t payload[];
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct DataObject {
|
||||||
|
ObjectHeader object;
|
||||||
|
uint64_t hash;
|
||||||
|
uint64_t next_hash_offset;
|
||||||
|
uint64_t next_field_offset;
|
||||||
|
uint64_t entry_offset; /* the first array entry we store inline */
|
||||||
|
uint64_t entry_array_offset;
|
||||||
|
uint64_t n_entries;
|
||||||
|
uint8_t payload[];
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct FieldObject {
|
||||||
|
ObjectHeader object;
|
||||||
|
uint64_t hash;
|
||||||
|
uint64_t next_hash_offset;
|
||||||
|
uint64_t head_data_offset;
|
||||||
|
uint64_t tail_data_offset;
|
||||||
|
uint8_t payload[];
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct EntryItem {
|
||||||
|
uint64_t object_offset;
|
||||||
|
uint64_t hash;
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct EntryObject {
|
||||||
|
ObjectHeader object;
|
||||||
|
uint64_t seqnum;
|
||||||
|
uint64_t realtime;
|
||||||
|
uint64_t monotonic;
|
||||||
|
sd_id128_t boot_id;
|
||||||
|
uint64_t xor_hash;
|
||||||
|
EntryItem items[];
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct HashItem {
|
||||||
|
uint64_t head_hash_offset;
|
||||||
|
uint64_t tail_hash_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct HashTableObject {
|
||||||
|
ObjectHeader object;
|
||||||
|
HashItem items[];
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct EntryArrayObject {
|
||||||
|
ObjectHeader object;
|
||||||
|
uint64_t next_entry_array_offset;
|
||||||
|
uint64_t items[];
|
||||||
|
};
|
||||||
|
|
||||||
|
union Object {
|
||||||
|
ObjectHeader object;
|
||||||
|
DataObject data;
|
||||||
|
FieldObject field;
|
||||||
|
EntryObject entry;
|
||||||
|
HashTableObject hash_table;
|
||||||
|
EntryArrayObject entry_array;
|
||||||
|
};
|
||||||
|
|
||||||
|
enum {
|
||||||
|
STATE_OFFLINE,
|
||||||
|
STATE_ONLINE,
|
||||||
|
STATE_ARCHIVED
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Header flags */
|
||||||
|
enum {
|
||||||
|
HEADER_INCOMPATIBLE_COMPRESSED = 1
|
||||||
|
};
|
||||||
|
|
||||||
|
_packed_ struct Header {
|
||||||
|
uint8_t signature[8]; /* "LPKSHHRH" */
|
||||||
|
uint32_t compatible_flags;
|
||||||
|
uint32_t incompatible_flags;
|
||||||
|
uint8_t state;
|
||||||
|
uint8_t reserved[7];
|
||||||
|
sd_id128_t file_id;
|
||||||
|
sd_id128_t machine_id;
|
||||||
|
sd_id128_t boot_id;
|
||||||
|
sd_id128_t seqnum_id;
|
||||||
|
uint64_t arena_offset;
|
||||||
|
uint64_t arena_size;
|
||||||
|
uint64_t data_hash_table_offset; /* for looking up data objects */
|
||||||
|
uint64_t data_hash_table_size;
|
||||||
|
uint64_t field_hash_table_offset; /* for looking up field objects */
|
||||||
|
uint64_t field_hash_table_size;
|
||||||
|
uint64_t tail_object_offset;
|
||||||
|
uint64_t n_objects;
|
||||||
|
uint64_t n_entries;
|
||||||
|
uint64_t seqnum;
|
||||||
|
uint64_t first_seqnum;
|
||||||
|
uint64_t entry_array_offset;
|
||||||
|
uint64_t head_entry_realtime;
|
||||||
|
uint64_t tail_entry_realtime;
|
||||||
|
uint64_t tail_entry_monotonic;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
2078
src/journal/journal-file.c
Normal file
2078
src/journal/journal-file.c
Normal file
File diff suppressed because it is too large
Load Diff
127
src/journal/journal-file.h
Normal file
127
src/journal/journal-file.h
Normal file
@ -0,0 +1,127 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef foojournalfilehfoo
|
||||||
|
#define foojournalfilehfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
|
||||||
|
#include "journal-def.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "sd-id128.h"
|
||||||
|
|
||||||
|
#define DEFAULT_MAX_SIZE (128ULL*1024ULL*1024ULL)
|
||||||
|
#define DEFAULT_MIN_SIZE (256ULL*1024ULL)
|
||||||
|
#define DEFAULT_KEEP_FREE (1ULL*1024ULL*1024ULL)
|
||||||
|
#define DEFAULT_MAX_USE (16ULL*1024ULL*1024ULL*16ULL)
|
||||||
|
|
||||||
|
typedef struct Window {
|
||||||
|
void *ptr;
|
||||||
|
uint64_t offset;
|
||||||
|
uint64_t size;
|
||||||
|
} Window;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
WINDOW_UNKNOWN = OBJECT_UNUSED,
|
||||||
|
WINDOW_DATA = OBJECT_DATA,
|
||||||
|
WINDOW_ENTRY = OBJECT_ENTRY,
|
||||||
|
WINDOW_DATA_HASH_TABLE = OBJECT_DATA_HASH_TABLE,
|
||||||
|
WINDOW_FIELD_HASH_TABLE = OBJECT_FIELD_HASH_TABLE,
|
||||||
|
WINDOW_ENTRY_ARRAY = OBJECT_ENTRY_ARRAY,
|
||||||
|
WINDOW_HEADER,
|
||||||
|
_WINDOW_MAX
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct JournalMetrics {
|
||||||
|
uint64_t max_size;
|
||||||
|
uint64_t min_size;
|
||||||
|
uint64_t keep_free;
|
||||||
|
uint64_t max_use;
|
||||||
|
} JournalMetrics;
|
||||||
|
|
||||||
|
typedef struct JournalFile {
|
||||||
|
int fd;
|
||||||
|
char *path;
|
||||||
|
struct stat last_stat;
|
||||||
|
mode_t mode;
|
||||||
|
int flags;
|
||||||
|
int prot;
|
||||||
|
bool writable;
|
||||||
|
bool tail_entry_monotonic_valid;
|
||||||
|
|
||||||
|
Header *header;
|
||||||
|
HashItem *data_hash_table;
|
||||||
|
HashItem *field_hash_table;
|
||||||
|
|
||||||
|
Window windows[_WINDOW_MAX];
|
||||||
|
|
||||||
|
uint64_t current_offset;
|
||||||
|
|
||||||
|
JournalMetrics metrics;
|
||||||
|
|
||||||
|
bool compress;
|
||||||
|
|
||||||
|
#ifdef HAVE_XZ
|
||||||
|
void *compress_buffer;
|
||||||
|
size_t compress_buffer_size;
|
||||||
|
#endif
|
||||||
|
} JournalFile;
|
||||||
|
|
||||||
|
typedef enum direction {
|
||||||
|
DIRECTION_UP,
|
||||||
|
DIRECTION_DOWN
|
||||||
|
} direction_t;
|
||||||
|
|
||||||
|
int journal_file_open(const char *fname, int flags, mode_t mode, JournalFile *template, JournalFile **ret);
|
||||||
|
void journal_file_close(JournalFile *j);
|
||||||
|
|
||||||
|
int journal_file_move_to_object(JournalFile *f, int type, uint64_t offset, Object **ret);
|
||||||
|
|
||||||
|
uint64_t journal_file_entry_n_items(Object *o);
|
||||||
|
|
||||||
|
int journal_file_append_entry(JournalFile *f, const dual_timestamp *ts, const struct iovec iovec[], unsigned n_iovec, uint64_t *seqno, Object **ret, uint64_t *offset);
|
||||||
|
|
||||||
|
int journal_file_find_data_object(JournalFile *f, const void *data, uint64_t size, Object **ret, uint64_t *offset);
|
||||||
|
int journal_file_find_data_object_with_hash(JournalFile *f, const void *data, uint64_t size, uint64_t hash, Object **ret, uint64_t *offset);
|
||||||
|
|
||||||
|
int journal_file_next_entry(JournalFile *f, Object *o, uint64_t p, direction_t direction, Object **ret, uint64_t *offset);
|
||||||
|
int journal_file_skip_entry(JournalFile *f, Object *o, uint64_t p, int64_t skip, Object **ret, uint64_t *offset);
|
||||||
|
|
||||||
|
int journal_file_next_entry_for_data(JournalFile *f, Object *o, uint64_t p, uint64_t data_offset, direction_t direction, Object **ret, uint64_t *offset);
|
||||||
|
|
||||||
|
int journal_file_move_to_entry_by_seqnum(JournalFile *f, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
|
||||||
|
int journal_file_move_to_entry_by_realtime(JournalFile *f, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
|
||||||
|
int journal_file_move_to_entry_by_monotonic(JournalFile *f, sd_id128_t boot_id, uint64_t monotonic, direction_t direction, Object **ret, uint64_t *offset);
|
||||||
|
|
||||||
|
int journal_file_move_to_entry_by_seqnum_for_data(JournalFile *f, uint64_t data_offset, uint64_t seqnum, direction_t direction, Object **ret, uint64_t *offset);
|
||||||
|
int journal_file_move_to_entry_by_realtime_for_data(JournalFile *f, uint64_t data_offset, uint64_t realtime, direction_t direction, Object **ret, uint64_t *offset);
|
||||||
|
|
||||||
|
int journal_file_copy_entry(JournalFile *from, JournalFile *to, Object *o, uint64_t p, uint64_t *seqnum, Object **ret, uint64_t *offset);
|
||||||
|
|
||||||
|
void journal_file_dump(JournalFile *f);
|
||||||
|
|
||||||
|
int journal_file_rotate(JournalFile **f);
|
||||||
|
|
||||||
|
int journal_directory_vacuum(const char *directory, uint64_t max_use, uint64_t min_free);
|
||||||
|
|
||||||
|
void journal_file_post_change(JournalFile *f);
|
||||||
|
|
||||||
|
#endif
|
83
src/journal/journal-internal.h
Normal file
83
src/journal/journal-internal.h
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef foojournalinternalhfoo
|
||||||
|
#define foojournalinternalhfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
#include "list.h"
|
||||||
|
#include "sd-id128.h"
|
||||||
|
|
||||||
|
typedef struct Match Match;
|
||||||
|
|
||||||
|
struct Match {
|
||||||
|
char *data;
|
||||||
|
size_t size;
|
||||||
|
uint64_t le_hash;
|
||||||
|
|
||||||
|
LIST_FIELDS(Match, matches);
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef enum location_type {
|
||||||
|
LOCATION_HEAD,
|
||||||
|
LOCATION_TAIL,
|
||||||
|
LOCATION_DISCRETE
|
||||||
|
} location_type_t;
|
||||||
|
|
||||||
|
typedef struct Location {
|
||||||
|
location_type_t type;
|
||||||
|
|
||||||
|
uint64_t seqnum;
|
||||||
|
sd_id128_t seqnum_id;
|
||||||
|
bool seqnum_set;
|
||||||
|
|
||||||
|
uint64_t realtime;
|
||||||
|
bool realtime_set;
|
||||||
|
|
||||||
|
uint64_t monotonic;
|
||||||
|
sd_id128_t boot_id;
|
||||||
|
bool monotonic_set;
|
||||||
|
|
||||||
|
uint64_t xor_hash;
|
||||||
|
bool xor_hash_set;
|
||||||
|
} Location;
|
||||||
|
|
||||||
|
struct sd_journal {
|
||||||
|
int flags;
|
||||||
|
|
||||||
|
Hashmap *files;
|
||||||
|
|
||||||
|
Location current_location;
|
||||||
|
JournalFile *current_file;
|
||||||
|
uint64_t current_field;
|
||||||
|
|
||||||
|
int inotify_fd;
|
||||||
|
Hashmap *inotify_wd_dirs;
|
||||||
|
Hashmap *inotify_wd_roots;
|
||||||
|
|
||||||
|
LIST_HEAD(Match, matches);
|
||||||
|
unsigned n_matches;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
275
src/journal/journal-rate-limit.c
Normal file
275
src/journal/journal-rate-limit.c
Normal file
@ -0,0 +1,275 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
|
#include "journal-rate-limit.h"
|
||||||
|
#include "list.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "hashmap.h"
|
||||||
|
|
||||||
|
#define POOLS_MAX 5
|
||||||
|
#define BUCKETS_MAX 127
|
||||||
|
#define GROUPS_MAX 2047
|
||||||
|
|
||||||
|
static const int priority_map[] = {
|
||||||
|
[LOG_EMERG] = 0,
|
||||||
|
[LOG_ALERT] = 0,
|
||||||
|
[LOG_CRIT] = 0,
|
||||||
|
[LOG_ERR] = 1,
|
||||||
|
[LOG_WARNING] = 2,
|
||||||
|
[LOG_NOTICE] = 3,
|
||||||
|
[LOG_INFO] = 3,
|
||||||
|
[LOG_DEBUG] = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct JournalRateLimitPool JournalRateLimitPool;
|
||||||
|
typedef struct JournalRateLimitGroup JournalRateLimitGroup;
|
||||||
|
|
||||||
|
struct JournalRateLimitPool {
|
||||||
|
usec_t begin;
|
||||||
|
unsigned num;
|
||||||
|
unsigned suppressed;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JournalRateLimitGroup {
|
||||||
|
JournalRateLimit *parent;
|
||||||
|
|
||||||
|
char *id;
|
||||||
|
JournalRateLimitPool pools[POOLS_MAX];
|
||||||
|
unsigned hash;
|
||||||
|
|
||||||
|
LIST_FIELDS(JournalRateLimitGroup, bucket);
|
||||||
|
LIST_FIELDS(JournalRateLimitGroup, lru);
|
||||||
|
};
|
||||||
|
|
||||||
|
struct JournalRateLimit {
|
||||||
|
usec_t interval;
|
||||||
|
unsigned burst;
|
||||||
|
|
||||||
|
JournalRateLimitGroup* buckets[BUCKETS_MAX];
|
||||||
|
JournalRateLimitGroup *lru, *lru_tail;
|
||||||
|
|
||||||
|
unsigned n_groups;
|
||||||
|
};
|
||||||
|
|
||||||
|
JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst) {
|
||||||
|
JournalRateLimit *r;
|
||||||
|
|
||||||
|
assert(interval > 0 || burst == 0);
|
||||||
|
|
||||||
|
r = new0(JournalRateLimit, 1);
|
||||||
|
if (!r)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
r->interval = interval;
|
||||||
|
r->burst = burst;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void journal_rate_limit_group_free(JournalRateLimitGroup *g) {
|
||||||
|
assert(g);
|
||||||
|
|
||||||
|
if (g->parent) {
|
||||||
|
assert(g->parent->n_groups > 0);
|
||||||
|
|
||||||
|
if (g->parent->lru_tail == g)
|
||||||
|
g->parent->lru_tail = g->lru_prev;
|
||||||
|
|
||||||
|
LIST_REMOVE(JournalRateLimitGroup, lru, g->parent->lru, g);
|
||||||
|
LIST_REMOVE(JournalRateLimitGroup, bucket, g->parent->buckets[g->hash % BUCKETS_MAX], g);
|
||||||
|
|
||||||
|
g->parent->n_groups --;
|
||||||
|
}
|
||||||
|
|
||||||
|
free(g->id);
|
||||||
|
free(g);
|
||||||
|
}
|
||||||
|
|
||||||
|
void journal_rate_limit_free(JournalRateLimit *r) {
|
||||||
|
assert(r);
|
||||||
|
|
||||||
|
while (r->lru)
|
||||||
|
journal_rate_limit_group_free(r->lru);
|
||||||
|
|
||||||
|
free(r);
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool journal_rate_limit_group_expired(JournalRateLimitGroup *g, usec_t ts) {
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
assert(g);
|
||||||
|
|
||||||
|
for (i = 0; i < POOLS_MAX; i++)
|
||||||
|
if (g->pools[i].begin + g->parent->interval >= ts)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void journal_rate_limit_vacuum(JournalRateLimit *r, usec_t ts) {
|
||||||
|
assert(r);
|
||||||
|
|
||||||
|
/* Makes room for at least one new item, but drop all
|
||||||
|
* expored items too. */
|
||||||
|
|
||||||
|
while (r->n_groups >= GROUPS_MAX ||
|
||||||
|
(r->lru_tail && journal_rate_limit_group_expired(r->lru_tail, ts)))
|
||||||
|
journal_rate_limit_group_free(r->lru_tail);
|
||||||
|
}
|
||||||
|
|
||||||
|
static JournalRateLimitGroup* journal_rate_limit_group_new(JournalRateLimit *r, const char *id, usec_t ts) {
|
||||||
|
JournalRateLimitGroup *g;
|
||||||
|
|
||||||
|
assert(r);
|
||||||
|
assert(id);
|
||||||
|
|
||||||
|
g = new0(JournalRateLimitGroup, 1);
|
||||||
|
if (!g)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
g->id = strdup(id);
|
||||||
|
if (!g->id)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
g->hash = string_hash_func(g->id);
|
||||||
|
|
||||||
|
journal_rate_limit_vacuum(r, ts);
|
||||||
|
|
||||||
|
LIST_PREPEND(JournalRateLimitGroup, bucket, r->buckets[g->hash % BUCKETS_MAX], g);
|
||||||
|
LIST_PREPEND(JournalRateLimitGroup, lru, r->lru, g);
|
||||||
|
if (!g->lru_next)
|
||||||
|
r->lru_tail = g;
|
||||||
|
r->n_groups ++;
|
||||||
|
|
||||||
|
g->parent = r;
|
||||||
|
return g;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
journal_rate_limit_group_free(g);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t u64log2(uint64_t n) {
|
||||||
|
unsigned r;
|
||||||
|
|
||||||
|
if (n <= 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
r = 0;
|
||||||
|
for (;;) {
|
||||||
|
n = n >> 1;
|
||||||
|
if (!n)
|
||||||
|
return r;
|
||||||
|
r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static unsigned burst_modulate(unsigned burst, uint64_t available) {
|
||||||
|
unsigned k;
|
||||||
|
|
||||||
|
/* Modulates the burst rate a bit with the amount of available
|
||||||
|
* disk space */
|
||||||
|
|
||||||
|
k = u64log2(available);
|
||||||
|
|
||||||
|
/* 1MB */
|
||||||
|
if (k <= 20)
|
||||||
|
return burst;
|
||||||
|
|
||||||
|
burst = (burst * (k-20)) / 4;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Example:
|
||||||
|
*
|
||||||
|
* <= 1MB = rate * 1
|
||||||
|
* 16MB = rate * 2
|
||||||
|
* 256MB = rate * 3
|
||||||
|
* 4GB = rate * 4
|
||||||
|
* 64GB = rate * 5
|
||||||
|
* 1TB = rate * 6
|
||||||
|
*/
|
||||||
|
|
||||||
|
return burst;
|
||||||
|
}
|
||||||
|
|
||||||
|
int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available) {
|
||||||
|
unsigned h;
|
||||||
|
JournalRateLimitGroup *g;
|
||||||
|
JournalRateLimitPool *p;
|
||||||
|
unsigned burst;
|
||||||
|
usec_t ts;
|
||||||
|
|
||||||
|
assert(id);
|
||||||
|
|
||||||
|
if (!r)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
if (r->interval == 0 || r->burst == 0)
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
burst = burst_modulate(r->burst, available);
|
||||||
|
|
||||||
|
ts = now(CLOCK_MONOTONIC);
|
||||||
|
|
||||||
|
h = string_hash_func(id);
|
||||||
|
g = r->buckets[h % BUCKETS_MAX];
|
||||||
|
|
||||||
|
LIST_FOREACH(bucket, g, g)
|
||||||
|
if (streq(g->id, id))
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (!g) {
|
||||||
|
g = journal_rate_limit_group_new(r, id, ts);
|
||||||
|
if (!g)
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
p = &g->pools[priority_map[priority]];
|
||||||
|
|
||||||
|
if (p->begin <= 0) {
|
||||||
|
p->suppressed = 0;
|
||||||
|
p->num = 1;
|
||||||
|
p->begin = ts;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->begin + r->interval < ts) {
|
||||||
|
unsigned s;
|
||||||
|
|
||||||
|
s = p->suppressed;
|
||||||
|
p->suppressed = 0;
|
||||||
|
p->num = 1;
|
||||||
|
p->begin = ts;
|
||||||
|
|
||||||
|
return 1 + s;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (p->num <= burst) {
|
||||||
|
p->num++;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->suppressed++;
|
||||||
|
return 0;
|
||||||
|
}
|
34
src/journal/journal-rate-limit.h
Normal file
34
src/journal/journal-rate-limit.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef foojournalratelimithfoo
|
||||||
|
#define foojournalratelimithfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include "macro.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
typedef struct JournalRateLimit JournalRateLimit;
|
||||||
|
|
||||||
|
JournalRateLimit *journal_rate_limit_new(usec_t interval, unsigned burst);
|
||||||
|
void journal_rate_limit_free(JournalRateLimit *r);
|
||||||
|
int journal_rate_limit_test(JournalRateLimit *r, const char *id, int priority, uint64_t available);
|
||||||
|
|
||||||
|
#endif
|
259
src/journal/journal-send.c
Normal file
259
src/journal/journal-send.c
Normal file
@ -0,0 +1,259 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/un.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
|
||||||
|
#include "sd-journal.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "socket-util.h"
|
||||||
|
|
||||||
|
/* We open a single fd, and we'll share it with the current process,
|
||||||
|
* all its threads, and all its subprocesses. This means we need to
|
||||||
|
* initialize it atomically, and need to operate on it atomically
|
||||||
|
* never assuming we are the only user */
|
||||||
|
|
||||||
|
static int journal_fd(void) {
|
||||||
|
int fd;
|
||||||
|
static int fd_plus_one = 0;
|
||||||
|
|
||||||
|
retry:
|
||||||
|
if (fd_plus_one > 0)
|
||||||
|
return fd_plus_one - 1;
|
||||||
|
|
||||||
|
fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (!__sync_bool_compare_and_swap(&fd_plus_one, 0, fd+1)) {
|
||||||
|
close_nointr_nofail(fd);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_journal_print(int priority, const char *format, ...) {
|
||||||
|
int r;
|
||||||
|
va_list ap;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
r = sd_journal_printv(priority, format, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_journal_printv(int priority, const char *format, va_list ap) {
|
||||||
|
char buffer[8 + LINE_MAX], p[11];
|
||||||
|
struct iovec iov[2];
|
||||||
|
|
||||||
|
if (priority < 0 || priority > 7)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!format)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
snprintf(p, sizeof(p), "PRIORITY=%i", priority & LOG_PRIMASK);
|
||||||
|
char_array_0(p);
|
||||||
|
|
||||||
|
memcpy(buffer, "MESSAGE=", 8);
|
||||||
|
vsnprintf(buffer+8, sizeof(buffer) - 8, format, ap);
|
||||||
|
char_array_0(buffer);
|
||||||
|
|
||||||
|
zero(iov);
|
||||||
|
IOVEC_SET_STRING(iov[0], buffer);
|
||||||
|
IOVEC_SET_STRING(iov[1], p);
|
||||||
|
|
||||||
|
return sd_journal_sendv(iov, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_journal_send(const char *format, ...) {
|
||||||
|
int r, n = 0, i = 0, j;
|
||||||
|
va_list ap;
|
||||||
|
struct iovec *iov = NULL;
|
||||||
|
|
||||||
|
va_start(ap, format);
|
||||||
|
while (format) {
|
||||||
|
struct iovec *c;
|
||||||
|
char *buffer;
|
||||||
|
|
||||||
|
if (i >= n) {
|
||||||
|
n = MAX(i*2, 4);
|
||||||
|
c = realloc(iov, n * sizeof(struct iovec));
|
||||||
|
if (!c) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
iov = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (vasprintf(&buffer, format, ap) < 0) {
|
||||||
|
r = -ENOMEM;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
IOVEC_SET_STRING(iov[i++], buffer);
|
||||||
|
|
||||||
|
format = va_arg(ap, char *);
|
||||||
|
}
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
r = sd_journal_sendv(iov, i);
|
||||||
|
|
||||||
|
fail:
|
||||||
|
for (j = 0; j < i; j++)
|
||||||
|
free(iov[j].iov_base);
|
||||||
|
|
||||||
|
free(iov);
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_journal_sendv(const struct iovec *iov, int n) {
|
||||||
|
int fd;
|
||||||
|
struct iovec *w;
|
||||||
|
uint64_t *l;
|
||||||
|
int i, j = 0;
|
||||||
|
struct msghdr mh;
|
||||||
|
struct sockaddr_un sa;
|
||||||
|
|
||||||
|
if (!iov || n <= 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
w = alloca(sizeof(struct iovec) * n * 5);
|
||||||
|
l = alloca(sizeof(uint64_t) * n);
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
char *c, *nl;
|
||||||
|
|
||||||
|
c = memchr(iov[i].iov_base, '=', iov[i].iov_len);
|
||||||
|
if (!c)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
nl = memchr(iov[i].iov_base, '\n', iov[i].iov_len);
|
||||||
|
if (nl) {
|
||||||
|
if (nl < c)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Already includes a newline? Bummer, then
|
||||||
|
* let's write the variable name, then a
|
||||||
|
* newline, then the size (64bit LE), followed
|
||||||
|
* by the data and a final newline */
|
||||||
|
|
||||||
|
w[j].iov_base = iov[i].iov_base;
|
||||||
|
w[j].iov_len = c - (char*) iov[i].iov_base;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
IOVEC_SET_STRING(w[j++], "\n");
|
||||||
|
|
||||||
|
l[i] = htole64(iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1);
|
||||||
|
w[j].iov_base = &l[i];
|
||||||
|
w[j].iov_len = sizeof(uint64_t);
|
||||||
|
j++;
|
||||||
|
|
||||||
|
w[j].iov_base = c + 1;
|
||||||
|
w[j].iov_len = iov[i].iov_len - (c - (char*) iov[i].iov_base) - 1;
|
||||||
|
j++;
|
||||||
|
|
||||||
|
} else
|
||||||
|
/* Nothing special? Then just add the line and
|
||||||
|
* append a newline */
|
||||||
|
w[j++] = iov[i];
|
||||||
|
|
||||||
|
IOVEC_SET_STRING(w[j++], "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = journal_fd();
|
||||||
|
if (fd < 0)
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
zero(sa);
|
||||||
|
sa.sun_family = AF_UNIX;
|
||||||
|
strncpy(sa.sun_path,"/run/systemd/journal", sizeof(sa.sun_path));
|
||||||
|
|
||||||
|
zero(mh);
|
||||||
|
mh.msg_name = &sa;
|
||||||
|
mh.msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path);
|
||||||
|
mh.msg_iov = w;
|
||||||
|
mh.msg_iovlen = j;
|
||||||
|
|
||||||
|
if (sendmsg(fd, &mh, MSG_NOSIGNAL) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_journal_stream_fd(const char *tag, int priority, int priority_prefix) {
|
||||||
|
union sockaddr_union sa;
|
||||||
|
int fd;
|
||||||
|
char *header;
|
||||||
|
size_t l;
|
||||||
|
ssize_t r;
|
||||||
|
|
||||||
|
if (priority < 0 || priority > 7)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC, 0);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
zero(sa);
|
||||||
|
sa.un.sun_family = AF_UNIX;
|
||||||
|
strncpy(sa.un.sun_path, "/run/systemd/stdout", sizeof(sa.un.sun_path));
|
||||||
|
|
||||||
|
r = connect(fd, &sa.sa, offsetof(union sockaddr_union, un.sun_path) + strlen(sa.un.sun_path));
|
||||||
|
if (r < 0) {
|
||||||
|
close_nointr_nofail(fd);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!tag)
|
||||||
|
tag = "";
|
||||||
|
|
||||||
|
l = strlen(tag);
|
||||||
|
header = alloca(l + 1 + 2 + 2 + 2);
|
||||||
|
|
||||||
|
memcpy(header, tag, l);
|
||||||
|
header[l++] = '\n';
|
||||||
|
header[l++] = '0' + priority;
|
||||||
|
header[l++] = '\n';
|
||||||
|
header[l++] = '0' + !!priority_prefix;
|
||||||
|
header[l++] = '\n';
|
||||||
|
header[l++] = '0';
|
||||||
|
header[l++] = '\n';
|
||||||
|
|
||||||
|
r = loop_write(fd, header, l, false);
|
||||||
|
if (r < 0) {
|
||||||
|
close_nointr_nofail(fd);
|
||||||
|
return (int) r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((size_t) r != l) {
|
||||||
|
close_nointr_nofail(fd);
|
||||||
|
return -errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
}
|
544
src/journal/journalctl.c
Normal file
544
src/journal/journalctl.c
Normal file
@ -0,0 +1,544 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <sys/poll.h>
|
||||||
|
#include <time.h>
|
||||||
|
#include <getopt.h>
|
||||||
|
|
||||||
|
#include "sd-journal.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "build.h"
|
||||||
|
#include "pager.h"
|
||||||
|
|
||||||
|
#define PRINT_THRESHOLD 128
|
||||||
|
|
||||||
|
static enum {
|
||||||
|
OUTPUT_SHORT,
|
||||||
|
OUTPUT_VERBOSE,
|
||||||
|
OUTPUT_EXPORT,
|
||||||
|
OUTPUT_JSON,
|
||||||
|
_OUTPUT_MAX
|
||||||
|
} arg_output = OUTPUT_SHORT;
|
||||||
|
|
||||||
|
static bool arg_follow = false;
|
||||||
|
static bool arg_show_all = false;
|
||||||
|
static bool arg_no_pager = false;
|
||||||
|
|
||||||
|
static bool contains_unprintable(const void *p, size_t l) {
|
||||||
|
const char *j;
|
||||||
|
|
||||||
|
for (j = p; j < (const char *) p + l; j++)
|
||||||
|
if (*j < ' ' || *j >= 127)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int output_short(sd_journal *j, unsigned line) {
|
||||||
|
int r;
|
||||||
|
uint64_t realtime;
|
||||||
|
time_t t;
|
||||||
|
struct tm tm;
|
||||||
|
char buf[64];
|
||||||
|
const void *data;
|
||||||
|
size_t length;
|
||||||
|
size_t n = 0;
|
||||||
|
|
||||||
|
assert(j);
|
||||||
|
|
||||||
|
r = sd_journal_get_realtime_usec(j, &realtime);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get realtime: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
t = (time_t) (realtime / USEC_PER_SEC);
|
||||||
|
if (strftime(buf, sizeof(buf), "%b %d %H:%M:%S", localtime_r(&t, &tm)) <= 0) {
|
||||||
|
log_error("Failed to format time.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs(buf, stdout);
|
||||||
|
n += strlen(buf);
|
||||||
|
|
||||||
|
if (sd_journal_get_data(j, "_HOSTNAME", &data, &length) >= 0 &&
|
||||||
|
(arg_show_all || (!contains_unprintable(data, length) &&
|
||||||
|
length < PRINT_THRESHOLD))) {
|
||||||
|
printf(" %.*s", (int) length - 10, ((const char*) data) + 10);
|
||||||
|
n += length - 10 + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sd_journal_get_data(j, "MESSAGE", &data, &length) >= 0) {
|
||||||
|
if (arg_show_all)
|
||||||
|
printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
|
||||||
|
else if (contains_unprintable(data, length))
|
||||||
|
fputs(" [blob data]", stdout);
|
||||||
|
else if (length - 8 + n < columns())
|
||||||
|
printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
|
||||||
|
else if (n < columns()) {
|
||||||
|
char *e;
|
||||||
|
|
||||||
|
e = ellipsize_mem((const char *) data + 8, length - 8, columns() - n - 2, 90);
|
||||||
|
|
||||||
|
if (!e)
|
||||||
|
printf(" %.*s", (int) length - 8, ((const char*) data) + 8);
|
||||||
|
else
|
||||||
|
printf(" %s", e);
|
||||||
|
|
||||||
|
free(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fputc('\n', stdout);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int output_verbose(sd_journal *j, unsigned line) {
|
||||||
|
const void *data;
|
||||||
|
size_t length;
|
||||||
|
char *cursor;
|
||||||
|
uint64_t realtime;
|
||||||
|
char ts[FORMAT_TIMESTAMP_MAX];
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(j);
|
||||||
|
|
||||||
|
r = sd_journal_get_realtime_usec(j, &realtime);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get realtime timestamp: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_journal_get_cursor(j, &cursor);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get cursor: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("%s [%s]\n",
|
||||||
|
format_timestamp(ts, sizeof(ts), realtime),
|
||||||
|
cursor);
|
||||||
|
|
||||||
|
free(cursor);
|
||||||
|
|
||||||
|
SD_JOURNAL_FOREACH_DATA(j, data, length) {
|
||||||
|
if (!arg_show_all && (length > PRINT_THRESHOLD ||
|
||||||
|
contains_unprintable(data, length))) {
|
||||||
|
const char *c;
|
||||||
|
|
||||||
|
c = memchr(data, '=', length);
|
||||||
|
if (!c) {
|
||||||
|
log_error("Invalid field.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("\t%.*s=[blob data]\n",
|
||||||
|
(int) (c - (const char*) data),
|
||||||
|
(const char*) data);
|
||||||
|
} else
|
||||||
|
printf("\t%.*s\n", (int) length, (const char*) data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int output_export(sd_journal *j, unsigned line) {
|
||||||
|
sd_id128_t boot_id;
|
||||||
|
char sid[33];
|
||||||
|
int r;
|
||||||
|
usec_t realtime, monotonic;
|
||||||
|
char *cursor;
|
||||||
|
const void *data;
|
||||||
|
size_t length;
|
||||||
|
|
||||||
|
assert(j);
|
||||||
|
|
||||||
|
r = sd_journal_get_realtime_usec(j, &realtime);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get realtime timestamp: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get monotonic timestamp: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_journal_get_cursor(j, &cursor);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get cursor: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(".cursor=%s\n"
|
||||||
|
".realtime=%llu\n"
|
||||||
|
".monotonic=%llu\n"
|
||||||
|
".boot_id=%s\n",
|
||||||
|
cursor,
|
||||||
|
(unsigned long long) realtime,
|
||||||
|
(unsigned long long) monotonic,
|
||||||
|
sd_id128_to_string(boot_id, sid));
|
||||||
|
|
||||||
|
free(cursor);
|
||||||
|
|
||||||
|
SD_JOURNAL_FOREACH_DATA(j, data, length) {
|
||||||
|
|
||||||
|
if (contains_unprintable(data, length)) {
|
||||||
|
const char *c;
|
||||||
|
uint64_t le64;
|
||||||
|
|
||||||
|
c = memchr(data, '=', length);
|
||||||
|
if (!c) {
|
||||||
|
log_error("Invalid field.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fwrite(data, c - (const char*) data, 1, stdout);
|
||||||
|
fputc('\n', stdout);
|
||||||
|
le64 = htole64(length - (c - (const char*) data) - 1);
|
||||||
|
fwrite(&le64, sizeof(le64), 1, stdout);
|
||||||
|
fwrite(c + 1, length - (c - (const char*) data) - 1, 1, stdout);
|
||||||
|
} else
|
||||||
|
fwrite(data, length, 1, stdout);
|
||||||
|
|
||||||
|
fputc('\n', stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputc('\n', stdout);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void json_escape(const char* p, size_t l) {
|
||||||
|
|
||||||
|
if (contains_unprintable(p, l)) {
|
||||||
|
bool not_first = false;
|
||||||
|
|
||||||
|
fputs("[ ", stdout);
|
||||||
|
|
||||||
|
while (l > 0) {
|
||||||
|
if (not_first)
|
||||||
|
printf(", %u", (uint8_t) *p);
|
||||||
|
else {
|
||||||
|
not_first = true;
|
||||||
|
printf("%u", (uint8_t) *p);
|
||||||
|
}
|
||||||
|
|
||||||
|
p++;
|
||||||
|
l--;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs(" ]", stdout);
|
||||||
|
} else {
|
||||||
|
fputc('\"', stdout);
|
||||||
|
|
||||||
|
while (l > 0) {
|
||||||
|
if (*p == '"' || *p == '\\') {
|
||||||
|
fputc('\\', stdout);
|
||||||
|
fputc(*p, stdout);
|
||||||
|
} else
|
||||||
|
fputc(*p, stdout);
|
||||||
|
|
||||||
|
p++;
|
||||||
|
l--;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputc('\"', stdout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int output_json(sd_journal *j, unsigned line) {
|
||||||
|
uint64_t realtime, monotonic;
|
||||||
|
char *cursor;
|
||||||
|
const void *data;
|
||||||
|
size_t length;
|
||||||
|
sd_id128_t boot_id;
|
||||||
|
char sid[33];
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(j);
|
||||||
|
|
||||||
|
r = sd_journal_get_realtime_usec(j, &realtime);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get realtime timestamp: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_journal_get_monotonic_usec(j, &monotonic, &boot_id);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get monotonic timestamp: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_journal_get_cursor(j, &cursor);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to get cursor: %s", strerror(-r));
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line == 1)
|
||||||
|
fputc('\n', stdout);
|
||||||
|
else
|
||||||
|
fputs(",\n", stdout);
|
||||||
|
|
||||||
|
printf("{\n"
|
||||||
|
"\t\".cursor\" : \"%s\",\n"
|
||||||
|
"\t\".realtime\" : %llu,\n"
|
||||||
|
"\t\".monotonic\" : %llu,\n"
|
||||||
|
"\t\".boot_id\" : \"%s\"",
|
||||||
|
cursor,
|
||||||
|
(unsigned long long) realtime,
|
||||||
|
(unsigned long long) monotonic,
|
||||||
|
sd_id128_to_string(boot_id, sid));
|
||||||
|
|
||||||
|
free(cursor);
|
||||||
|
|
||||||
|
SD_JOURNAL_FOREACH_DATA(j, data, length) {
|
||||||
|
const char *c;
|
||||||
|
|
||||||
|
c = memchr(data, '=', length);
|
||||||
|
if (!c) {
|
||||||
|
log_error("Invalid field.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs(",\n\t", stdout);
|
||||||
|
json_escape(data, c - (const char*) data);
|
||||||
|
fputs(" : ", stdout);
|
||||||
|
json_escape(c + 1, length - (c - (const char*) data) - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
fputs("\n}", stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int (*output_funcs[_OUTPUT_MAX])(sd_journal*j, unsigned line) = {
|
||||||
|
[OUTPUT_SHORT] = output_short,
|
||||||
|
[OUTPUT_VERBOSE] = output_verbose,
|
||||||
|
[OUTPUT_EXPORT] = output_export,
|
||||||
|
[OUTPUT_JSON] = output_json
|
||||||
|
};
|
||||||
|
|
||||||
|
static int help(void) {
|
||||||
|
|
||||||
|
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
|
||||||
|
"Send control commands to or query the login manager.\n\n"
|
||||||
|
" -h --help Show this help\n"
|
||||||
|
" --version Show package version\n"
|
||||||
|
" --no-pager Do not pipe output into a pager\n"
|
||||||
|
" -a --all Show all properties, including long and unprintable\n"
|
||||||
|
" -f --follow Follow journal\n"
|
||||||
|
" -o --output=STRING Change output mode (short, verbose, export, json)\n",
|
||||||
|
program_invocation_short_name);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int parse_argv(int argc, char *argv[]) {
|
||||||
|
|
||||||
|
enum {
|
||||||
|
ARG_VERSION = 0x100,
|
||||||
|
ARG_NO_PAGER
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct option options[] = {
|
||||||
|
{ "help", no_argument, NULL, 'h' },
|
||||||
|
{ "version" , no_argument, NULL, ARG_VERSION },
|
||||||
|
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
|
||||||
|
{ "follow", no_argument, NULL, 'f' },
|
||||||
|
{ "output", required_argument, NULL, 'o' },
|
||||||
|
{ "all", no_argument, NULL, 'a' },
|
||||||
|
{ NULL, 0, NULL, 0 }
|
||||||
|
};
|
||||||
|
|
||||||
|
int c;
|
||||||
|
|
||||||
|
assert(argc >= 0);
|
||||||
|
assert(argv);
|
||||||
|
|
||||||
|
while ((c = getopt_long(argc, argv, "hfo:a", options, NULL)) >= 0) {
|
||||||
|
|
||||||
|
switch (c) {
|
||||||
|
|
||||||
|
case 'h':
|
||||||
|
help();
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case ARG_VERSION:
|
||||||
|
puts(PACKAGE_STRING);
|
||||||
|
puts(DISTRIBUTION);
|
||||||
|
puts(SYSTEMD_FEATURES);
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
case ARG_NO_PAGER:
|
||||||
|
arg_no_pager = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
arg_follow = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'o':
|
||||||
|
if (streq(optarg, "short"))
|
||||||
|
arg_output = OUTPUT_SHORT;
|
||||||
|
else if (streq(optarg, "verbose"))
|
||||||
|
arg_output = OUTPUT_VERBOSE;
|
||||||
|
else if (streq(optarg, "export"))
|
||||||
|
arg_output = OUTPUT_EXPORT;
|
||||||
|
else if (streq(optarg, "json"))
|
||||||
|
arg_output = OUTPUT_JSON;
|
||||||
|
else {
|
||||||
|
log_error("Unknown output '%s'.", optarg);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'a':
|
||||||
|
arg_show_all = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '?':
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
default:
|
||||||
|
log_error("Unknown option code %c", c);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
int r, i, fd;
|
||||||
|
sd_journal *j = NULL;
|
||||||
|
unsigned line = 0;
|
||||||
|
|
||||||
|
log_parse_environment();
|
||||||
|
log_open();
|
||||||
|
|
||||||
|
r = parse_argv(argc, argv);
|
||||||
|
if (r <= 0)
|
||||||
|
goto finish;
|
||||||
|
|
||||||
|
r = sd_journal_open(&j, 0);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to open journal: %s", strerror(-r));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = optind; i < argc; i++) {
|
||||||
|
r = sd_journal_add_match(j, argv[i], strlen(argv[i]));
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to add match: %s", strerror(-r));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = sd_journal_get_fd(j);
|
||||||
|
if (fd < 0) {
|
||||||
|
log_error("Failed to get wakeup fd: %s", strerror(-fd));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_journal_seek_head(j);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to seek to head: %s", strerror(-r));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arg_no_pager && !arg_follow) {
|
||||||
|
columns();
|
||||||
|
pager_open();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_output == OUTPUT_JSON) {
|
||||||
|
fputc('[', stdout);
|
||||||
|
fflush(stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
struct pollfd pollfd;
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
r = sd_journal_next(j);
|
||||||
|
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to iterate through journal: %s", strerror(-r));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
line ++;
|
||||||
|
|
||||||
|
r = output_funcs[arg_output](j, line);
|
||||||
|
if (r < 0)
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!arg_follow)
|
||||||
|
break;
|
||||||
|
|
||||||
|
zero(pollfd);
|
||||||
|
pollfd.fd = fd;
|
||||||
|
pollfd.events = POLLIN;
|
||||||
|
|
||||||
|
if (poll(&pollfd, 1, -1) < 0) {
|
||||||
|
if (errno == EINTR)
|
||||||
|
break;
|
||||||
|
|
||||||
|
log_error("poll(): %m");
|
||||||
|
r = -errno;
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = sd_journal_process(j);
|
||||||
|
if (r < 0) {
|
||||||
|
log_error("Failed to process: %s", strerror(-r));
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (arg_output == OUTPUT_JSON)
|
||||||
|
fputs("\n]\n", stdout);
|
||||||
|
|
||||||
|
finish:
|
||||||
|
if (j)
|
||||||
|
sd_journal_close(j);
|
||||||
|
|
||||||
|
pager_close();
|
||||||
|
|
||||||
|
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
|
}
|
1909
src/journal/journald.c
Normal file
1909
src/journal/journald.c
Normal file
File diff suppressed because it is too large
Load Diff
1003
src/journal/lookup3.c
Normal file
1003
src/journal/lookup3.c
Normal file
File diff suppressed because it is too large
Load Diff
25
src/journal/lookup3.h
Normal file
25
src/journal/lookup3.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef foolookup3hfoo
|
||||||
|
#define foolookup3hfoo
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
uint32_t jenkins_hashword(const uint32_t *k, size_t length, uint32_t initval);
|
||||||
|
void jenkins_hashword2(const uint32_t *k, size_t length, uint32_t *pc, uint32_t *pb);
|
||||||
|
|
||||||
|
uint32_t jenkins_hashlittle(const void *key, size_t length, uint32_t initval);
|
||||||
|
void jenkins_hashlittle2(const void *key, size_t length, uint32_t *pc, uint32_t *pb);
|
||||||
|
|
||||||
|
uint32_t jenkins_hashbig(const void *key, size_t length, uint32_t initval);
|
||||||
|
|
||||||
|
static inline uint64_t hash64(const void *data, size_t length) {
|
||||||
|
uint32_t a = 0, b = 0;
|
||||||
|
|
||||||
|
jenkins_hashlittle2(data, length, &a, &b);
|
||||||
|
|
||||||
|
return ((uint64_t) a << 32ULL) | (uint64_t) b;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
1573
src/journal/sd-journal.c
Normal file
1573
src/journal/sd-journal.c
Normal file
File diff suppressed because it is too large
Load Diff
125
src/journal/sd-journal.h
Normal file
125
src/journal/sd-journal.h
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef foojournalhfoo
|
||||||
|
#define foojournalhfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <stdarg.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
|
||||||
|
#include "sd-id128.h"
|
||||||
|
|
||||||
|
/* TODO:
|
||||||
|
*
|
||||||
|
* - OR of matches is borked...
|
||||||
|
* - extend hash tables table as we go
|
||||||
|
* - accelerate looking for "all hostnames" and suchlike.
|
||||||
|
* - hookup with systemctl
|
||||||
|
* - handle incomplete header
|
||||||
|
* - write unit files
|
||||||
|
*
|
||||||
|
* - local deserializer
|
||||||
|
* - http server
|
||||||
|
* - message catalog
|
||||||
|
*
|
||||||
|
* - check LE/BE conversion for 8bit, 16bit, 32bit values
|
||||||
|
* - cryptographic hash
|
||||||
|
* - think about manipulations of header
|
||||||
|
* - implement audit gateway
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Write to daemon */
|
||||||
|
|
||||||
|
int sd_journal_print(int piority, const char *format, ...) __attribute__ ((format (printf, 2, 3)));
|
||||||
|
int sd_journal_printv(int priority, const char *format, va_list ap);
|
||||||
|
|
||||||
|
int sd_journal_send(const char *format, ...) __attribute__((sentinel));
|
||||||
|
int sd_journal_sendv(const struct iovec *iov, int n);
|
||||||
|
|
||||||
|
int sd_journal_stream_fd(const char *tag, int priority, int priority_prefix);
|
||||||
|
|
||||||
|
/* Browse journal stream */
|
||||||
|
|
||||||
|
typedef struct sd_journal sd_journal;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SD_JOURNAL_LOCAL_ONLY = 1,
|
||||||
|
SD_JOURNAL_RUNTIME_ONLY = 2,
|
||||||
|
SD_JOURNAL_SYSTEM_ONLY = 4
|
||||||
|
};
|
||||||
|
|
||||||
|
int sd_journal_open(sd_journal **ret, int flags);
|
||||||
|
void sd_journal_close(sd_journal *j);
|
||||||
|
|
||||||
|
int sd_journal_previous(sd_journal *j);
|
||||||
|
int sd_journal_next(sd_journal *j);
|
||||||
|
|
||||||
|
int sd_journal_previous_skip(sd_journal *j, uint64_t skip);
|
||||||
|
int sd_journal_next_skip(sd_journal *j, uint64_t skip);
|
||||||
|
|
||||||
|
int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret);
|
||||||
|
int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id);
|
||||||
|
int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *l);
|
||||||
|
int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *l);
|
||||||
|
void sd_journal_restart_data(sd_journal *j);
|
||||||
|
|
||||||
|
int sd_journal_add_match(sd_journal *j, const void *data, size_t size);
|
||||||
|
void sd_journal_flush_matches(sd_journal *j);
|
||||||
|
|
||||||
|
int sd_journal_seek_head(sd_journal *j);
|
||||||
|
int sd_journal_seek_tail(sd_journal *j);
|
||||||
|
int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec);
|
||||||
|
int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec);
|
||||||
|
int sd_journal_seek_cursor(sd_journal *j, const char *cursor);
|
||||||
|
|
||||||
|
int sd_journal_get_cursor(sd_journal *j, char **cursor);
|
||||||
|
|
||||||
|
int sd_journal_query_unique(sd_journal *j, const char *field); /* missing */
|
||||||
|
int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l); /* missing */
|
||||||
|
void sd_journal_restart_unique(sd_journal *j); /* missing */
|
||||||
|
|
||||||
|
enum {
|
||||||
|
SD_JOURNAL_NOP,
|
||||||
|
SD_JOURNAL_APPEND,
|
||||||
|
SD_JOURNAL_INVALIDATE_ADD,
|
||||||
|
SD_JOURNAL_INVALIDATE_REMOVE
|
||||||
|
};
|
||||||
|
|
||||||
|
int sd_journal_get_fd(sd_journal *j);
|
||||||
|
int sd_journal_process(sd_journal *j);
|
||||||
|
|
||||||
|
#define SD_JOURNAL_FOREACH(j) \
|
||||||
|
if (sd_journal_seek_head(j) >= 0) \
|
||||||
|
while (sd_journal_next(j) > 0)
|
||||||
|
|
||||||
|
#define SD_JOURNAL_FOREACH_BACKWARDS(j) \
|
||||||
|
if (sd_journal_seek_tail(j) >= 0) \
|
||||||
|
while (sd_journal_previous(j) > 0)
|
||||||
|
|
||||||
|
#define SD_JOURNAL_FOREACH_DATA(j, data, l) \
|
||||||
|
for (sd_journal_restart_data(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; )
|
||||||
|
|
||||||
|
#define SD_JOURNAL_FOREACH_UNIQUE(j, data, l) \
|
||||||
|
for (sd_journal_restart_unique(j); sd_journal_enumerate_data((j), &(data), &(l)) > 0; )
|
||||||
|
|
||||||
|
#endif
|
119
src/journal/test-journal.c
Normal file
119
src/journal/test-journal.c
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "sd-journal.h"
|
||||||
|
#include "journal-file.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
dual_timestamp ts;
|
||||||
|
JournalFile *f;
|
||||||
|
struct iovec iovec;
|
||||||
|
static const char test[] = "test", test2[] = "test2";
|
||||||
|
Object *o;
|
||||||
|
uint64_t p;
|
||||||
|
|
||||||
|
log_set_max_level(LOG_DEBUG);
|
||||||
|
|
||||||
|
unlink("test.journal");
|
||||||
|
|
||||||
|
assert_se(journal_file_open("test.journal", O_RDWR|O_CREAT, 0666, NULL, &f) == 0);
|
||||||
|
|
||||||
|
dual_timestamp_get(&ts);
|
||||||
|
|
||||||
|
iovec.iov_base = (void*) test;
|
||||||
|
iovec.iov_len = strlen(test);
|
||||||
|
assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
|
||||||
|
|
||||||
|
iovec.iov_base = (void*) test2;
|
||||||
|
iovec.iov_len = strlen(test2);
|
||||||
|
assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
|
||||||
|
|
||||||
|
iovec.iov_base = (void*) test;
|
||||||
|
iovec.iov_len = strlen(test);
|
||||||
|
assert_se(journal_file_append_entry(f, &ts, &iovec, 1, NULL, NULL, NULL) == 0);
|
||||||
|
|
||||||
|
journal_file_dump(f);
|
||||||
|
|
||||||
|
assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 1);
|
||||||
|
|
||||||
|
assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 2);
|
||||||
|
|
||||||
|
assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 3);
|
||||||
|
|
||||||
|
assert(journal_file_next_entry(f, o, p, DIRECTION_DOWN, &o, &p) == 0);
|
||||||
|
|
||||||
|
assert(journal_file_next_entry(f, NULL, 0, DIRECTION_DOWN, &o, &p) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 1);
|
||||||
|
|
||||||
|
assert(journal_file_skip_entry(f, o, p, 2, &o, &p) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 3);
|
||||||
|
|
||||||
|
assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 1);
|
||||||
|
|
||||||
|
assert(journal_file_skip_entry(f, o, p, -2, &o, &p) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 1);
|
||||||
|
|
||||||
|
assert(journal_file_find_data_object(f, test, strlen(test), NULL, &p) == 1);
|
||||||
|
assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 1);
|
||||||
|
|
||||||
|
assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 3);
|
||||||
|
|
||||||
|
assert(journal_file_find_data_object(f, test2, strlen(test2), NULL, &p) == 1);
|
||||||
|
assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_UP, &o, NULL) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 2);
|
||||||
|
|
||||||
|
assert(journal_file_next_entry_for_data(f, NULL, 0, p, DIRECTION_DOWN, &o, NULL) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 2);
|
||||||
|
|
||||||
|
assert(journal_file_find_data_object(f, "quux", 4, NULL, &p) == 0);
|
||||||
|
|
||||||
|
assert(journal_file_move_to_entry_by_seqnum(f, 1, DIRECTION_DOWN, &o, NULL) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 1);
|
||||||
|
|
||||||
|
assert(journal_file_move_to_entry_by_seqnum(f, 3, DIRECTION_DOWN, &o, NULL) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 3);
|
||||||
|
|
||||||
|
assert(journal_file_move_to_entry_by_seqnum(f, 2, DIRECTION_DOWN, &o, NULL) == 1);
|
||||||
|
assert(le64toh(o->entry.seqnum) == 2);
|
||||||
|
|
||||||
|
assert(journal_file_move_to_entry_by_seqnum(f, 10, DIRECTION_DOWN, &o, NULL) == 0);
|
||||||
|
|
||||||
|
journal_file_rotate(&f);
|
||||||
|
journal_file_rotate(&f);
|
||||||
|
|
||||||
|
journal_file_close(f);
|
||||||
|
|
||||||
|
journal_directory_vacuum(".", 3000000, 0);
|
||||||
|
|
||||||
|
log_error("Exiting...");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -65,63 +65,72 @@ static void server_done(Server *s) {
|
|||||||
fdset_free(s->syslog_fds);
|
fdset_free(s->syslog_fds);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int server_init(Server *s, unsigned n_sockets) {
|
static int server_init(Server *s) {
|
||||||
int r;
|
int i, r, n;
|
||||||
unsigned i;
|
|
||||||
struct epoll_event ev;
|
struct epoll_event ev;
|
||||||
sigset_t mask;
|
sigset_t mask;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(n_sockets > 0);
|
|
||||||
|
|
||||||
zero(*s);
|
zero(*s);
|
||||||
|
|
||||||
s->kmsg_fd = s->signal_fd = -1;
|
s->kmsg_fd = s->signal_fd = -1;
|
||||||
|
|
||||||
if ((s->epoll_fd = epoll_create1(EPOLL_CLOEXEC)) < 0) {
|
s->epoll_fd = epoll_create1(EPOLL_CLOEXEC);
|
||||||
r = -errno;
|
if (s->epoll_fd < 0) {
|
||||||
log_error("Failed to create epoll object: %s", strerror(errno));
|
log_error("Failed to create epoll object: %m");
|
||||||
goto fail;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(s->syslog_fds = fdset_new())) {
|
s->syslog_fds = fdset_new();
|
||||||
r = -ENOMEM;
|
if (!s->syslog_fds) {
|
||||||
log_error("Failed to allocate file descriptor set: %s", strerror(errno));
|
log_error("Failed to allocate file descriptor set: %s", strerror(ENOMEM));
|
||||||
goto fail;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < n_sockets; i++) {
|
n = sd_listen_fds(true);
|
||||||
int fd;
|
if (n < 0) {
|
||||||
|
log_error("Failed to read listening file descriptors from environment: %s", strerror(-n));
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (n <= 0 || n > SERVER_FD_MAX) {
|
||||||
|
log_error("No or too many file descriptors passed.");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < n; i++) {
|
||||||
|
int fd, one = 1;
|
||||||
|
|
||||||
fd = SD_LISTEN_FDS_START+i;
|
fd = SD_LISTEN_FDS_START+i;
|
||||||
|
|
||||||
if ((r = sd_is_socket(fd, AF_UNSPEC, SOCK_DGRAM, -1)) < 0) {
|
r = sd_is_socket(fd, AF_UNSPEC, SOCK_DGRAM, -1);
|
||||||
|
if (r < 0) {
|
||||||
log_error("Failed to determine file descriptor type: %s", strerror(-r));
|
log_error("Failed to determine file descriptor type: %s", strerror(-r));
|
||||||
goto fail;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!r) {
|
if (!r) {
|
||||||
log_error("Wrong file descriptor type.");
|
log_error("Wrong file descriptor type.");
|
||||||
r = -EINVAL;
|
return -EINVAL;
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zero(ev);
|
zero(ev);
|
||||||
ev.events = EPOLLIN;
|
ev.events = EPOLLIN;
|
||||||
ev.data.fd = fd;
|
ev.data.fd = fd;
|
||||||
if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
|
if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) {
|
||||||
r = -errno;
|
log_error("Failed to add server fd to epoll object: %m");
|
||||||
log_error("Failed to add server fd to epoll object: %s", strerror(errno));
|
return -errno;
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((r = fdset_put(s->syslog_fds, fd)) < 0) {
|
r = fdset_put(s->syslog_fds, fd);
|
||||||
|
if (r < 0) {
|
||||||
log_error("Failed to store file descriptor in set: %s", strerror(-r));
|
log_error("Failed to store file descriptor in set: %s", strerror(-r));
|
||||||
goto fail;
|
return r;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s->kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC)) < 0) {
|
s->kmsg_fd = open("/dev/kmsg", O_WRONLY|O_NOCTTY|O_CLOEXEC);
|
||||||
|
if (s->kmsg_fd < 0) {
|
||||||
log_error("Failed to open /dev/kmsg for logging: %m");
|
log_error("Failed to open /dev/kmsg for logging: %m");
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
@ -130,7 +139,8 @@ static int server_init(Server *s, unsigned n_sockets) {
|
|||||||
sigset_add_many(&mask, SIGINT, SIGTERM, -1);
|
sigset_add_many(&mask, SIGINT, SIGTERM, -1);
|
||||||
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
|
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
|
||||||
|
|
||||||
if ((s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
|
s->signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
|
||||||
|
if (s->signal_fd < 0) {
|
||||||
log_error("signalfd(): %m");
|
log_error("signalfd(): %m");
|
||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
@ -145,80 +155,6 @@ static int server_init(Server *s, unsigned n_sockets) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
fail:
|
|
||||||
server_done(s);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void skip_date(const char **buf) {
|
|
||||||
enum {
|
|
||||||
LETTER,
|
|
||||||
SPACE,
|
|
||||||
NUMBER,
|
|
||||||
SPACE_OR_NUMBER,
|
|
||||||
COLON
|
|
||||||
} sequence[] = {
|
|
||||||
LETTER, LETTER, LETTER,
|
|
||||||
SPACE,
|
|
||||||
SPACE_OR_NUMBER, NUMBER,
|
|
||||||
SPACE,
|
|
||||||
SPACE_OR_NUMBER, NUMBER,
|
|
||||||
COLON,
|
|
||||||
SPACE_OR_NUMBER, NUMBER,
|
|
||||||
COLON,
|
|
||||||
SPACE_OR_NUMBER, NUMBER,
|
|
||||||
SPACE
|
|
||||||
};
|
|
||||||
|
|
||||||
const char *p;
|
|
||||||
unsigned i;
|
|
||||||
|
|
||||||
assert(buf);
|
|
||||||
assert(*buf);
|
|
||||||
|
|
||||||
p = *buf;
|
|
||||||
|
|
||||||
for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
|
|
||||||
|
|
||||||
if (!*p)
|
|
||||||
return;
|
|
||||||
|
|
||||||
switch (sequence[i]) {
|
|
||||||
|
|
||||||
case SPACE:
|
|
||||||
if (*p != ' ')
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SPACE_OR_NUMBER:
|
|
||||||
if (*p == ' ')
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* fall through */
|
|
||||||
|
|
||||||
case NUMBER:
|
|
||||||
if (*p < '0' || *p > '9')
|
|
||||||
return;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case LETTER:
|
|
||||||
if (!(*p >= 'A' && *p <= 'Z') &&
|
|
||||||
!(*p >= 'a' && *p <= 'z'))
|
|
||||||
return;
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case COLON:
|
|
||||||
if (*p != ':')
|
|
||||||
return;
|
|
||||||
break;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
*buf = p;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int read_process(const char **buf, struct iovec *iovec) {
|
static int read_process(const char **buf, struct iovec *iovec) {
|
||||||
@ -263,28 +199,6 @@ static int read_process(const char **buf, struct iovec *iovec) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void skip_pid(const char **buf) {
|
|
||||||
const char *p;
|
|
||||||
|
|
||||||
assert(buf);
|
|
||||||
assert(*buf);
|
|
||||||
|
|
||||||
p = *buf;
|
|
||||||
|
|
||||||
if (*p != '[')
|
|
||||||
return;
|
|
||||||
|
|
||||||
p++;
|
|
||||||
p += strspn(p, "0123456789");
|
|
||||||
|
|
||||||
if (*p != ']')
|
|
||||||
return;
|
|
||||||
|
|
||||||
p++;
|
|
||||||
|
|
||||||
*buf = p;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int write_message(Server *s, const char *buf, struct ucred *ucred) {
|
static int write_message(Server *s, const char *buf, struct ucred *ucred) {
|
||||||
ssize_t k;
|
ssize_t k;
|
||||||
char priority[6], pid[16];
|
char priority[6], pid[16];
|
||||||
@ -311,14 +225,14 @@ static int write_message(Server *s, const char *buf, struct ucred *ucred) {
|
|||||||
IOVEC_SET_STRING(iovec[i++], priority);
|
IOVEC_SET_STRING(iovec[i++], priority);
|
||||||
|
|
||||||
/* Second, skip date */
|
/* Second, skip date */
|
||||||
skip_date(&buf);
|
skip_syslog_date((char**) &buf);
|
||||||
|
|
||||||
/* Then, add process if set */
|
/* Then, add process if set */
|
||||||
if (read_process(&buf, &iovec[i]) > 0)
|
if (read_process(&buf, &iovec[i]) > 0)
|
||||||
i++;
|
i++;
|
||||||
else if (ucred &&
|
else if (ucred &&
|
||||||
ucred->pid > 0 &&
|
ucred->pid > 0 &&
|
||||||
get_process_name(ucred->pid, &process) >= 0)
|
get_process_comm(ucred->pid, &process) >= 0)
|
||||||
IOVEC_SET_STRING(iovec[i++], process);
|
IOVEC_SET_STRING(iovec[i++], process);
|
||||||
|
|
||||||
/* Skip the stored PID if we have a better one */
|
/* Skip the stored PID if we have a better one */
|
||||||
@ -327,7 +241,7 @@ static int write_message(Server *s, const char *buf, struct ucred *ucred) {
|
|||||||
char_array_0(pid);
|
char_array_0(pid);
|
||||||
IOVEC_SET_STRING(iovec[i++], pid);
|
IOVEC_SET_STRING(iovec[i++], pid);
|
||||||
|
|
||||||
skip_pid(&buf);
|
skip_syslog_pid((char**) &buf);
|
||||||
|
|
||||||
if (*buf == ':')
|
if (*buf == ':')
|
||||||
buf++;
|
buf++;
|
||||||
@ -365,7 +279,8 @@ static int process_event(Server *s, struct epoll_event *ev) {
|
|||||||
struct signalfd_siginfo sfsi;
|
struct signalfd_siginfo sfsi;
|
||||||
ssize_t n;
|
ssize_t n;
|
||||||
|
|
||||||
if ((n = read(s->signal_fd, &sfsi, sizeof(sfsi))) != sizeof(sfsi)) {
|
n = read(s->signal_fd, &sfsi, sizeof(sfsi));
|
||||||
|
if (n != sizeof(sfsi)) {
|
||||||
|
|
||||||
if (n >= 0)
|
if (n >= 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@ -404,7 +319,8 @@ static int process_event(Server *s, struct epoll_event *ev) {
|
|||||||
msghdr.msg_control = &control;
|
msghdr.msg_control = &control;
|
||||||
msghdr.msg_controllen = sizeof(control);
|
msghdr.msg_controllen = sizeof(control);
|
||||||
|
|
||||||
if ((n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT)) < 0) {
|
n = recvmsg(ev->data.fd, &msghdr, MSG_DONTWAIT);
|
||||||
|
if (n < 0) {
|
||||||
|
|
||||||
if (errno == EINTR || errno == EAGAIN)
|
if (errno == EINTR || errno == EAGAIN)
|
||||||
return 1;
|
return 1;
|
||||||
@ -421,12 +337,14 @@ static int process_event(Server *s, struct epoll_event *ev) {
|
|||||||
else
|
else
|
||||||
ucred = NULL;
|
ucred = NULL;
|
||||||
|
|
||||||
if ((e = memchr(buf, '\n', n)))
|
e = memchr(buf, '\n', n);
|
||||||
|
if (e)
|
||||||
*e = 0;
|
*e = 0;
|
||||||
else
|
else
|
||||||
buf[n] = 0;
|
buf[n] = 0;
|
||||||
|
|
||||||
if ((k = write_message(s, strstrip(buf), ucred)) < 0)
|
k = write_message(s, strstrip(buf), ucred);
|
||||||
|
if (k < 0)
|
||||||
return k;
|
return k;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -436,7 +354,7 @@ static int process_event(Server *s, struct epoll_event *ev) {
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
Server server;
|
Server server;
|
||||||
int r = EXIT_FAILURE, n;
|
int r;
|
||||||
|
|
||||||
if (getppid() != 1) {
|
if (getppid() != 1) {
|
||||||
log_error("This program should be invoked by init only.");
|
log_error("This program should be invoked by init only.");
|
||||||
@ -454,18 +372,9 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
umask(0022);
|
umask(0022);
|
||||||
|
|
||||||
if ((n = sd_listen_fds(true)) < 0) {
|
r = server_init(&server);
|
||||||
log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
|
if (r < 0)
|
||||||
return EXIT_FAILURE;
|
goto finish;
|
||||||
}
|
|
||||||
|
|
||||||
if (n <= 0 || n > SERVER_FD_MAX) {
|
|
||||||
log_error("No or too many file descriptors passed.");
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (server_init(&server, (unsigned) n) < 0)
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
|
|
||||||
log_debug("systemd-kmsg-syslogd running as pid %lu", (unsigned long) getpid());
|
log_debug("systemd-kmsg-syslogd running as pid %lu", (unsigned long) getpid());
|
||||||
|
|
||||||
@ -475,36 +384,33 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
struct epoll_event event;
|
struct epoll_event event;
|
||||||
int k;
|
|
||||||
|
|
||||||
if ((k = epoll_wait(server.epoll_fd, &event, 1, -1)) < 0) {
|
r = epoll_wait(server.epoll_fd, &event, 1, -1);
|
||||||
|
if (r < 0) {
|
||||||
|
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
log_error("epoll_wait() failed: %m");
|
log_error("epoll_wait() failed: %m");
|
||||||
goto fail;
|
r = -errno;
|
||||||
}
|
goto finish;
|
||||||
|
} else if (r == 0)
|
||||||
if (k <= 0)
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if ((k = process_event(&server, &event)) < 0)
|
r = process_event(&server, &event);
|
||||||
goto fail;
|
if (r < 0)
|
||||||
|
goto finish;
|
||||||
if (k == 0)
|
else if (r == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = EXIT_SUCCESS;
|
|
||||||
|
|
||||||
log_debug("systemd-kmsg-syslogd stopped as pid %lu", (unsigned long) getpid());
|
log_debug("systemd-kmsg-syslogd stopped as pid %lu", (unsigned long) getpid());
|
||||||
|
|
||||||
fail:
|
finish:
|
||||||
sd_notify(false,
|
sd_notify(false,
|
||||||
"STATUS=Shutting down...");
|
"STATUS=Shutting down...");
|
||||||
|
|
||||||
server_done(&server);
|
server_done(&server);
|
||||||
|
|
||||||
return r;
|
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||||
}
|
}
|
||||||
|
22
src/libsystemd-id128.sym
Normal file
22
src/libsystemd-id128.sym
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
***/
|
||||||
|
|
||||||
|
/* Original symbols from systemd v38 */
|
||||||
|
|
||||||
|
LIBSYSTEMD_ID128_38 {
|
||||||
|
global:
|
||||||
|
sd_id128_to_string;
|
||||||
|
sd_id128_from_string;
|
||||||
|
sd_id128_randomize;
|
||||||
|
sd_id128_make_v4_uuid;
|
||||||
|
sd_id128_get_machine;
|
||||||
|
sd_id128_get_boot;
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
};
|
45
src/libsystemd-journal.sym
Normal file
45
src/libsystemd-journal.sym
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
***/
|
||||||
|
|
||||||
|
/* Original symbols from systemd v38 */
|
||||||
|
|
||||||
|
LIBSYSTEMD_JOURNAL_38 {
|
||||||
|
global:
|
||||||
|
sd_journal_print;
|
||||||
|
sd_journal_printv;
|
||||||
|
sd_journal_send;
|
||||||
|
sd_journal_sendv;
|
||||||
|
sd_journal_stream_fd;
|
||||||
|
sd_journal_open;
|
||||||
|
sd_journal_close;
|
||||||
|
sd_journal_previous;
|
||||||
|
sd_journal_next;
|
||||||
|
sd_journal_previous_skip;
|
||||||
|
sd_journal_next_skip;
|
||||||
|
sd_journal_get_realtime_usec;
|
||||||
|
sd_journal_get_monotonic_usec;
|
||||||
|
sd_journal_get_data;
|
||||||
|
sd_journal_enumerate_data;
|
||||||
|
sd_journal_restart_data;
|
||||||
|
sd_journal_add_match;
|
||||||
|
sd_journal_flush_matches;
|
||||||
|
sd_journal_seek_head;
|
||||||
|
sd_journal_seek_tail;
|
||||||
|
sd_journal_seek_monotonic_usec;
|
||||||
|
sd_journal_seek_realtime_usec;
|
||||||
|
sd_journal_seek_cursor;
|
||||||
|
sd_journal_get_cursor;
|
||||||
|
sd_journal_query_unique;
|
||||||
|
sd_journal_enumerate_unique;
|
||||||
|
sd_journal_restart_unique;
|
||||||
|
sd_journal_get_fd;
|
||||||
|
sd_journal_process;
|
||||||
|
local:
|
||||||
|
*;
|
||||||
|
};
|
@ -393,7 +393,7 @@ static void print_session_status_info(SessionStatusInfo *i) {
|
|||||||
|
|
||||||
printf("\t Leader: %u", (unsigned) i->leader);
|
printf("\t Leader: %u", (unsigned) i->leader);
|
||||||
|
|
||||||
get_process_name(i->leader, &t);
|
get_process_comm(i->leader, &t);
|
||||||
if (t) {
|
if (t) {
|
||||||
printf(" (%s)", t);
|
printf(" (%s)", t);
|
||||||
free(t);
|
free(t);
|
||||||
|
@ -27,46 +27,7 @@
|
|||||||
|
|
||||||
#include "logind-acl.h"
|
#include "logind-acl.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "acl-util.h"
|
||||||
static int find_acl(acl_t acl, uid_t uid, acl_entry_t *entry) {
|
|
||||||
acl_entry_t i;
|
|
||||||
int found;
|
|
||||||
|
|
||||||
assert(acl);
|
|
||||||
assert(entry);
|
|
||||||
|
|
||||||
for (found = acl_get_entry(acl, ACL_FIRST_ENTRY, &i);
|
|
||||||
found > 0;
|
|
||||||
found = acl_get_entry(acl, ACL_NEXT_ENTRY, &i)) {
|
|
||||||
|
|
||||||
acl_tag_t tag;
|
|
||||||
uid_t *u;
|
|
||||||
bool b;
|
|
||||||
|
|
||||||
if (acl_get_tag_type(i, &tag) < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
if (tag != ACL_USER)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
u = acl_get_qualifier(i);
|
|
||||||
if (!u)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
b = *u == uid;
|
|
||||||
acl_free(u);
|
|
||||||
|
|
||||||
if (b) {
|
|
||||||
*entry = i;
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (found < 0)
|
|
||||||
return -errno;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int flush_acl(acl_t acl) {
|
static int flush_acl(acl_t acl) {
|
||||||
acl_entry_t i;
|
acl_entry_t i;
|
||||||
@ -125,7 +86,7 @@ int devnode_acl(const char *path,
|
|||||||
} else if (del && old_uid > 0) {
|
} else if (del && old_uid > 0) {
|
||||||
acl_entry_t entry;
|
acl_entry_t entry;
|
||||||
|
|
||||||
r = find_acl(acl, old_uid, &entry);
|
r = acl_find_uid(acl, old_uid, &entry);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
@ -144,7 +105,7 @@ int devnode_acl(const char *path,
|
|||||||
acl_permset_t permset;
|
acl_permset_t permset;
|
||||||
int rd, wt;
|
int rd, wt;
|
||||||
|
|
||||||
r = find_acl(acl, new_uid, &entry);
|
r = acl_find_uid(acl, new_uid, &entry);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
goto finish;
|
goto finish;
|
||||||
|
|
||||||
|
@ -31,21 +31,12 @@
|
|||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "sd-id128.h"
|
||||||
static void make_v4_uuid(unsigned char *id) {
|
|
||||||
/* Stolen from generate_random_uuid() of drivers/char/random.c
|
|
||||||
* in the kernel sources */
|
|
||||||
|
|
||||||
/* Set UUID version to 4 --- truly random generation */
|
|
||||||
id[6] = (id[6] & 0x0F) | 0x40;
|
|
||||||
|
|
||||||
/* Set the UUID variant to DCE */
|
|
||||||
id[8] = (id[8] & 0x3F) | 0x80;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int generate(char id[34]) {
|
static int generate(char id[34]) {
|
||||||
int fd;
|
int fd, r;
|
||||||
unsigned char buf[16], *p;
|
unsigned char *p;
|
||||||
|
sd_id128_t buf;
|
||||||
char *q;
|
char *q;
|
||||||
ssize_t k;
|
ssize_t k;
|
||||||
|
|
||||||
@ -68,26 +59,13 @@ static int generate(char id[34]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* If that didn't work, generate a random machine id */
|
/* If that didn't work, generate a random machine id */
|
||||||
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
r = sd_id128_randomize(&buf);
|
||||||
if (fd < 0) {
|
if (r < 0) {
|
||||||
log_error("Failed to open /dev/urandom: %m");
|
log_error("Failed to open /dev/urandom: %s", strerror(-r));
|
||||||
return -errno;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
k = loop_read(fd, buf, sizeof(buf), false);
|
for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += 2) {
|
||||||
close_nointr_nofail(fd);
|
|
||||||
|
|
||||||
if (k != sizeof(buf)) {
|
|
||||||
log_error("Failed to read /dev/urandom: %s", strerror(k < 0 ? -k : EIO));
|
|
||||||
return k < 0 ? (int) k : -EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Turn this into a valid v4 UUID, to be nice. Note that we
|
|
||||||
* only guarantee this for newly generated UUIDs, not for
|
|
||||||
* pre-existing ones.*/
|
|
||||||
make_v4_uuid(buf);
|
|
||||||
|
|
||||||
for (p = buf, q = id; p < buf + sizeof(buf); p++, q += 2) {
|
|
||||||
q[0] = hexchar(*p >> 4);
|
q[0] = hexchar(*p >> 4);
|
||||||
q[1] = hexchar(*p & 15);
|
q[1] = hexchar(*p & 15);
|
||||||
}
|
}
|
||||||
|
@ -149,7 +149,7 @@ static inline size_t ALIGN_TO(size_t l, size_t ali) {
|
|||||||
char *_s = (char *)(s); \
|
char *_s = (char *)(s); \
|
||||||
_i->iov_base = _s; \
|
_i->iov_base = _s; \
|
||||||
_i->iov_len = strlen(_s); \
|
_i->iov_len = strlen(_s); \
|
||||||
} while(false);
|
} while(false)
|
||||||
|
|
||||||
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
|
static inline size_t IOVEC_TOTAL_SIZE(const struct iovec *i, unsigned n) {
|
||||||
unsigned j;
|
unsigned j;
|
||||||
|
@ -2032,7 +2032,7 @@ static int manager_dispatch_sigchld(Manager *m) {
|
|||||||
if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
|
if (si.si_code == CLD_EXITED || si.si_code == CLD_KILLED || si.si_code == CLD_DUMPED) {
|
||||||
char *name = NULL;
|
char *name = NULL;
|
||||||
|
|
||||||
get_process_name(si.si_pid, &name);
|
get_process_comm(si.si_pid, &name);
|
||||||
log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
|
log_debug("Got SIGCHLD for process %lu (%s)", (unsigned long) si.si_pid, strna(name));
|
||||||
free(name);
|
free(name);
|
||||||
}
|
}
|
||||||
@ -2117,7 +2117,7 @@ static int manager_process_signal_fd(Manager *m) {
|
|||||||
if (sfsi.ssi_pid > 0) {
|
if (sfsi.ssi_pid > 0) {
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
|
|
||||||
get_process_name(sfsi.ssi_pid, &p);
|
get_process_comm(sfsi.ssi_pid, &p);
|
||||||
|
|
||||||
log_debug("Received SIG%s from PID %lu (%s).",
|
log_debug("Received SIG%s from PID %lu (%s).",
|
||||||
signal_to_string(sfsi.ssi_signo),
|
signal_to_string(sfsi.ssi_signo),
|
||||||
|
@ -163,42 +163,24 @@ static int get_user_data(
|
|||||||
|
|
||||||
const char *username = NULL;
|
const char *username = NULL;
|
||||||
struct passwd *pw = NULL;
|
struct passwd *pw = NULL;
|
||||||
|
uid_t uid;
|
||||||
int r;
|
int r;
|
||||||
bool have_loginuid = false;
|
|
||||||
char *s;
|
|
||||||
|
|
||||||
assert(handle);
|
assert(handle);
|
||||||
assert(ret_username);
|
assert(ret_username);
|
||||||
assert(ret_pw);
|
assert(ret_pw);
|
||||||
|
|
||||||
if (have_effective_cap(CAP_AUDIT_CONTROL) > 0) {
|
r = audit_loginuid_from_pid(0, &uid);
|
||||||
/* Only use audit login uid if we are executed with
|
if (r >= 0)
|
||||||
* sufficient capabilities so that pam_loginuid could
|
pw = pam_modutil_getpwuid(handle, uid);
|
||||||
* do its job. If we are lacking the CAP_AUDIT_CONTROL
|
else {
|
||||||
* capabality we most likely are being run in a
|
r = pam_get_user(handle, &username, NULL);
|
||||||
* container and /proc/self/loginuid is useless since
|
if (r != PAM_SUCCESS) {
|
||||||
* it probably contains a uid of the host system. */
|
|
||||||
|
|
||||||
if (read_one_line_file("/proc/self/loginuid", &s) >= 0) {
|
|
||||||
uid_t uid;
|
|
||||||
|
|
||||||
r = parse_uid(s, &uid);
|
|
||||||
free(s);
|
|
||||||
|
|
||||||
if (r >= 0 && uid != (uint32_t) -1) {
|
|
||||||
have_loginuid = true;
|
|
||||||
pw = pam_modutil_getpwuid(handle, uid);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!have_loginuid) {
|
|
||||||
if ((r = pam_get_user(handle, &username, NULL)) != PAM_SUCCESS) {
|
|
||||||
pam_syslog(handle, LOG_ERR, "Failed to get user name.");
|
pam_syslog(handle, LOG_ERR, "Failed to get user name.");
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!username || !*username) {
|
if (isempty(username)) {
|
||||||
pam_syslog(handle, LOG_ERR, "User name not valid.");
|
pam_syslog(handle, LOG_ERR, "User name not valid.");
|
||||||
return PAM_AUTH_ERR;
|
return PAM_AUTH_ERR;
|
||||||
}
|
}
|
||||||
|
@ -54,12 +54,14 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
umask(0022);
|
umask(0022);
|
||||||
|
|
||||||
if (!(f = setmntent("/etc/fstab", "r"))) {
|
f = setmntent("/etc/fstab", "r");
|
||||||
|
if (!f) {
|
||||||
log_error("Failed to open /etc/fstab: %m");
|
log_error("Failed to open /etc/fstab: %m");
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
|
pids = hashmap_new(trivial_hash_func, trivial_compare_func);
|
||||||
|
if (!pids) {
|
||||||
log_error("Failed to allocate set");
|
log_error("Failed to allocate set");
|
||||||
goto finish;
|
goto finish;
|
||||||
}
|
}
|
||||||
@ -76,9 +78,10 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
log_debug("Remounting %s", me->mnt_dir);
|
log_debug("Remounting %s", me->mnt_dir);
|
||||||
|
|
||||||
if ((pid = fork()) < 0) {
|
pid = fork();
|
||||||
|
if (pid < 0) {
|
||||||
log_error("Failed to fork: %m");
|
log_error("Failed to fork: %m");
|
||||||
ret = 1;
|
ret = EXIT_FAILURE;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -101,8 +104,15 @@ int main(int argc, char *argv[]) {
|
|||||||
/* Parent */
|
/* Parent */
|
||||||
|
|
||||||
s = strdup(me->mnt_dir);
|
s = strdup(me->mnt_dir);
|
||||||
|
if (!s) {
|
||||||
|
log_error("Out of memory.");
|
||||||
|
ret = EXIT_FAILURE;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if ((k = hashmap_put(pids, UINT_TO_PTR(pid), s)) < 0) {
|
|
||||||
|
k = hashmap_put(pids, UINT_TO_PTR(pid), s);
|
||||||
|
if (k < 0) {
|
||||||
log_error("Failed to add PID to set: %s", strerror(-k));
|
log_error("Failed to add PID to set: %s", strerror(-k));
|
||||||
ret = EXIT_FAILURE;
|
ret = EXIT_FAILURE;
|
||||||
continue;
|
continue;
|
||||||
@ -124,7 +134,8 @@ int main(int argc, char *argv[]) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
|
s = hashmap_remove(pids, UINT_TO_PTR(si.si_pid));
|
||||||
|
if (s) {
|
||||||
if (!is_clean_exit(si.si_code, si.si_status)) {
|
if (!is_clean_exit(si.si_code, si.si_status)) {
|
||||||
if (si.si_code == CLD_EXITED)
|
if (si.si_code == CLD_EXITED)
|
||||||
log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status);
|
log_error("/bin/mount for %s exited with exit status %i.", s, si.si_status);
|
||||||
|
210
src/sd-id128.c
Normal file
210
src/sd-id128.c
Normal file
@ -0,0 +1,210 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <fcntl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "sd-id128.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
|
char *sd_id128_to_string(sd_id128_t id, char s[33]) {
|
||||||
|
unsigned n;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
|
||||||
|
for (n = 0; n < 16; n++) {
|
||||||
|
s[n*2] = hexchar(id.bytes[n] >> 4);
|
||||||
|
s[n*2+1] = hexchar(id.bytes[n] & 0xF);
|
||||||
|
}
|
||||||
|
|
||||||
|
s[32] = 0;
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_id128_from_string(const char s[33], sd_id128_t *ret) {
|
||||||
|
unsigned n;
|
||||||
|
sd_id128_t t;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
for (n = 0; n < 16; n++) {
|
||||||
|
int a, b;
|
||||||
|
|
||||||
|
a = unhexchar(s[n*2]);
|
||||||
|
if (a < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
b = unhexchar(s[n*2+1]);
|
||||||
|
if (b < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
t.bytes[n] = (a << 4) | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s[32] != 0)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
*ret = t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
sd_id128_t sd_id128_make_v4_uuid(sd_id128_t id) {
|
||||||
|
/* Stolen from generate_random_uuid() of drivers/char/random.c
|
||||||
|
* in the kernel sources */
|
||||||
|
|
||||||
|
/* Set UUID version to 4 --- truly random generation */
|
||||||
|
id.bytes[6] = (id.bytes[6] & 0x0F) | 0x40;
|
||||||
|
|
||||||
|
/* Set the UUID variant to DCE */
|
||||||
|
id.bytes[8] = (id.bytes[8] & 0x3F) | 0x80;
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_id128_get_machine(sd_id128_t *ret) {
|
||||||
|
static __thread sd_id128_t saved_machine_id;
|
||||||
|
static __thread bool saved_machine_id_valid = false;
|
||||||
|
int fd;
|
||||||
|
char buf[32];
|
||||||
|
ssize_t k;
|
||||||
|
unsigned j;
|
||||||
|
sd_id128_t t;
|
||||||
|
|
||||||
|
if (saved_machine_id_valid) {
|
||||||
|
*ret = saved_machine_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
k = loop_read(fd, buf, 32, false);
|
||||||
|
close_nointr_nofail(fd);
|
||||||
|
|
||||||
|
if (k < 0)
|
||||||
|
return (int) k;
|
||||||
|
|
||||||
|
if (k < 32)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
for (j = 0; j < 16; j++) {
|
||||||
|
int a, b;
|
||||||
|
|
||||||
|
a = unhexchar(buf[j*2]);
|
||||||
|
b = unhexchar(buf[j*2+1]);
|
||||||
|
|
||||||
|
if (a < 0 || b < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
t.bytes[j] = a << 4 | b;
|
||||||
|
}
|
||||||
|
|
||||||
|
saved_machine_id = t;
|
||||||
|
saved_machine_id_valid = true;
|
||||||
|
|
||||||
|
*ret = t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_id128_get_boot(sd_id128_t *ret) {
|
||||||
|
static __thread sd_id128_t saved_boot_id;
|
||||||
|
static __thread bool saved_boot_id_valid = false;
|
||||||
|
int fd;
|
||||||
|
char buf[36];
|
||||||
|
ssize_t k;
|
||||||
|
unsigned j;
|
||||||
|
sd_id128_t t;
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (saved_boot_id_valid) {
|
||||||
|
*ret = saved_boot_id;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
fd = open("/proc/sys/kernel/random/boot_id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
k = loop_read(fd, buf, 36, false);
|
||||||
|
close_nointr_nofail(fd);
|
||||||
|
|
||||||
|
if (k < 0)
|
||||||
|
return (int) k;
|
||||||
|
|
||||||
|
if (k < 36)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
for (j = 0, p = buf; j < 16; j++) {
|
||||||
|
int a, b;
|
||||||
|
|
||||||
|
if (*p == '-')
|
||||||
|
p++;
|
||||||
|
|
||||||
|
a = unhexchar(p[0]);
|
||||||
|
b = unhexchar(p[1]);
|
||||||
|
|
||||||
|
if (a < 0 || b < 0)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
t.bytes[j] = a << 4 | b;
|
||||||
|
|
||||||
|
p += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
saved_boot_id = t;
|
||||||
|
saved_boot_id_valid = true;
|
||||||
|
|
||||||
|
*ret = t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int sd_id128_randomize(sd_id128_t *ret) {
|
||||||
|
int fd;
|
||||||
|
ssize_t k;
|
||||||
|
sd_id128_t t;
|
||||||
|
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
fd = open("/dev/urandom", O_RDONLY|O_CLOEXEC|O_NOCTTY);
|
||||||
|
if (fd < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
k = loop_read(fd, &t, 16, false);
|
||||||
|
close_nointr_nofail(fd);
|
||||||
|
|
||||||
|
if (k < 0)
|
||||||
|
return (int) k;
|
||||||
|
|
||||||
|
if (k < 16)
|
||||||
|
return -EIO;
|
||||||
|
|
||||||
|
/* Turn this into a valid v4 UUID, to be nice. Note that we
|
||||||
|
* only guarantee this for newly generated UUIDs, not for
|
||||||
|
* pre-existing ones.*/
|
||||||
|
|
||||||
|
*ret = sd_id128_make_v4_uuid(t);
|
||||||
|
return 0;
|
||||||
|
}
|
56
src/sd-id128.h
Normal file
56
src/sd-id128.h
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
#ifndef fooid128hfoo
|
||||||
|
#define fooid128hfoo
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <inttypes.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
typedef union sd_id128 sd_id128_t;
|
||||||
|
|
||||||
|
union sd_id128 {
|
||||||
|
uint8_t bytes[16];
|
||||||
|
uint64_t qwords[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
char *sd_id128_to_string(sd_id128_t id, char s[33]);
|
||||||
|
|
||||||
|
int sd_id128_from_string(const char s[33], sd_id128_t *ret);
|
||||||
|
|
||||||
|
int sd_id128_randomize(sd_id128_t *ret);
|
||||||
|
|
||||||
|
sd_id128_t sd_id128_make_v4_uuid(sd_id128_t id);
|
||||||
|
|
||||||
|
int sd_id128_get_machine(sd_id128_t *ret);
|
||||||
|
|
||||||
|
int sd_id128_get_boot(sd_id128_t *ret);
|
||||||
|
|
||||||
|
#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \
|
||||||
|
((sd_id128_t) { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \
|
||||||
|
0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }})
|
||||||
|
|
||||||
|
static inline bool sd_id128_equal(sd_id128_t a, sd_id128_t b) {
|
||||||
|
return memcmp(&a, &b, 16) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -236,7 +236,6 @@ static int stream_log(Stream *s, char *p, usec_t ts) {
|
|||||||
|
|
||||||
writev(console, iovec, 4);
|
writev(console, iovec, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -366,7 +365,6 @@ static int stream_process(Stream *s, usec_t ts) {
|
|||||||
return -errno;
|
return -errno;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (l == 0)
|
if (l == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -409,8 +407,10 @@ static int stream_new(Server *s, int server_fd) {
|
|||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
|
assert(server_fd >= 0);
|
||||||
|
|
||||||
if ((fd = accept4(server_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC)) < 0)
|
fd = accept4(server_fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
|
||||||
|
if (fd < 0)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (s->n_streams >= STREAMS_MAX) {
|
if (s->n_streams >= STREAMS_MAX) {
|
||||||
@ -649,7 +649,8 @@ int main(int argc, char *argv[]) {
|
|||||||
|
|
||||||
umask(0022);
|
umask(0022);
|
||||||
|
|
||||||
if ((n = sd_listen_fds(true)) < 0) {
|
n = sd_listen_fds(true);
|
||||||
|
if (n < 0) {
|
||||||
log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
|
log_error("Failed to read listening file descriptors from environment: %s", strerror(-r));
|
||||||
return EXIT_FAILURE;
|
return EXIT_FAILURE;
|
||||||
}
|
}
|
||||||
|
@ -2199,7 +2199,7 @@ static void print_status_info(UnitStatusInfo *i) {
|
|||||||
|
|
||||||
if (i->running) {
|
if (i->running) {
|
||||||
char *t = NULL;
|
char *t = NULL;
|
||||||
get_process_name(i->main_pid, &t);
|
get_process_comm(i->main_pid, &t);
|
||||||
if (t) {
|
if (t) {
|
||||||
printf(" (%s)", t);
|
printf(" (%s)", t);
|
||||||
free(t);
|
free(t);
|
||||||
@ -2233,7 +2233,7 @@ static void print_status_info(UnitStatusInfo *i) {
|
|||||||
|
|
||||||
printf(" Control: %u", (unsigned) i->control_pid);
|
printf(" Control: %u", (unsigned) i->control_pid);
|
||||||
|
|
||||||
get_process_name(i->control_pid, &t);
|
get_process_comm(i->control_pid, &t);
|
||||||
if (t) {
|
if (t) {
|
||||||
printf(" (%s)", t);
|
printf(" (%s)", t);
|
||||||
free(t);
|
free(t);
|
||||||
|
49
src/test-id128.c
Normal file
49
src/test-id128.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
|
||||||
|
|
||||||
|
/***
|
||||||
|
This file is part of systemd.
|
||||||
|
|
||||||
|
Copyright 2011 Lennart Poettering
|
||||||
|
|
||||||
|
systemd is free software; you can redistribute it and/or modify it
|
||||||
|
under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
systemd is distributed in the hope that it will be useful, but
|
||||||
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with systemd; If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
***/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "sd-id128.h"
|
||||||
|
#include "util.h"
|
||||||
|
#include "macro.h"
|
||||||
|
|
||||||
|
#define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10)
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
sd_id128_t id, id2;
|
||||||
|
char t[33];
|
||||||
|
|
||||||
|
assert_se(sd_id128_randomize(&id) == 0);
|
||||||
|
printf("random: %s\n", sd_id128_to_string(id, t));
|
||||||
|
|
||||||
|
assert_se(sd_id128_from_string(t, &id2) == 0);
|
||||||
|
assert_se(sd_id128_equal(id, id2));
|
||||||
|
|
||||||
|
assert_se(sd_id128_get_machine(&id) == 0);
|
||||||
|
printf("machine: %s\n", sd_id128_to_string(id, t));
|
||||||
|
|
||||||
|
assert_se(sd_id128_get_boot(&id) == 0);
|
||||||
|
printf("boot: %s\n", sd_id128_to_string(id, t));
|
||||||
|
|
||||||
|
printf("waldi: %s\n", sd_id128_to_string(ID128_WALDI, t));
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
328
src/util.c
328
src/util.c
@ -55,6 +55,7 @@
|
|||||||
#include <linux/rtc.h>
|
#include <linux/rtc.h>
|
||||||
#include <glob.h>
|
#include <glob.h>
|
||||||
#include <grp.h>
|
#include <grp.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
@ -73,7 +74,7 @@ size_t page_size(void) {
|
|||||||
static __thread size_t pgsz = 0;
|
static __thread size_t pgsz = 0;
|
||||||
long r;
|
long r;
|
||||||
|
|
||||||
if (_likely_(pgsz))
|
if (_likely_(pgsz > 0))
|
||||||
return pgsz;
|
return pgsz;
|
||||||
|
|
||||||
assert_se((r = sysconf(_SC_PAGESIZE)) > 0);
|
assert_se((r = sysconf(_SC_PAGESIZE)) > 0);
|
||||||
@ -993,46 +994,51 @@ char *truncate_nl(char *s) {
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_process_name(pid_t pid, char **name) {
|
int get_process_comm(pid_t pid, char **name) {
|
||||||
char *p;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(pid >= 1);
|
|
||||||
assert(name);
|
assert(name);
|
||||||
|
|
||||||
if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
|
if (pid == 0)
|
||||||
return -ENOMEM;
|
r = read_one_line_file("/proc/self/comm", name);
|
||||||
|
else {
|
||||||
|
char *p;
|
||||||
|
if (asprintf(&p, "/proc/%lu/comm", (unsigned long) pid) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
r = read_one_line_file(p, name);
|
r = read_one_line_file(p, name);
|
||||||
free(p);
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
if (r < 0)
|
return r;
|
||||||
return r;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int get_process_cmdline(pid_t pid, size_t max_length, char **line) {
|
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line) {
|
||||||
char *p, *r, *k;
|
char *r, *k;
|
||||||
int c;
|
int c;
|
||||||
bool space = false;
|
bool space = false;
|
||||||
size_t left;
|
size_t left;
|
||||||
FILE *f;
|
FILE *f;
|
||||||
|
|
||||||
assert(pid >= 1);
|
|
||||||
assert(max_length > 0);
|
assert(max_length > 0);
|
||||||
assert(line);
|
assert(line);
|
||||||
|
|
||||||
if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
|
if (pid == 0)
|
||||||
return -ENOMEM;
|
f = fopen("/proc/self/cmdline", "re");
|
||||||
|
else {
|
||||||
|
char *p;
|
||||||
|
if (asprintf(&p, "/proc/%lu/cmdline", (unsigned long) pid) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
f = fopen(p, "re");
|
f = fopen(p, "re");
|
||||||
free(p);
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
if (!f)
|
if (!f)
|
||||||
return -errno;
|
return -errno;
|
||||||
|
|
||||||
if (!(r = new(char, max_length))) {
|
r = new(char, max_length);
|
||||||
|
if (!r) {
|
||||||
fclose(f);
|
fclose(f);
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
@ -1076,13 +1082,17 @@ int get_process_cmdline(pid_t pid, size_t max_length, char **line) {
|
|||||||
|
|
||||||
free(r);
|
free(r);
|
||||||
|
|
||||||
if ((h = get_process_name(pid, &t)) < 0)
|
if (!comm_fallback)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
h = get_process_comm(pid, &t);
|
||||||
|
if (h < 0)
|
||||||
return h;
|
return h;
|
||||||
|
|
||||||
h = asprintf(&r, "[%s]", t);
|
r = join("[", t, "]", NULL);
|
||||||
free(t);
|
free(t);
|
||||||
|
|
||||||
if (h < 0)
|
if (!r)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1090,6 +1100,25 @@ int get_process_cmdline(pid_t pid, size_t max_length, char **line) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int get_process_exe(pid_t pid, char **name) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(name);
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
r = readlink_malloc("/proc/self/exe", name);
|
||||||
|
else {
|
||||||
|
char *p;
|
||||||
|
if (asprintf(&p, "/proc/%lu/exe", (unsigned long) pid) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = readlink_malloc(p, name);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
char *strnappend(const char *s, const char *suffix, size_t b) {
|
char *strnappend(const char *s, const char *suffix, size_t b) {
|
||||||
size_t a;
|
size_t a;
|
||||||
char *r;
|
char *r;
|
||||||
@ -2645,7 +2674,7 @@ int acquire_terminal(const char *name, bool fail, bool force, bool ignore_tiocst
|
|||||||
ssize_t l;
|
ssize_t l;
|
||||||
struct inotify_event *e;
|
struct inotify_event *e;
|
||||||
|
|
||||||
if ((l = read(notify, &inotify_buffer, sizeof(inotify_buffer))) < 0) {
|
if ((l = read(notify, inotify_buffer, sizeof(inotify_buffer))) < 0) {
|
||||||
|
|
||||||
if (errno == EINTR)
|
if (errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
@ -2856,7 +2885,8 @@ ssize_t loop_write(int fd, const void *buf, size_t nbytes, bool do_poll) {
|
|||||||
while (nbytes > 0) {
|
while (nbytes > 0) {
|
||||||
ssize_t k;
|
ssize_t k;
|
||||||
|
|
||||||
if ((k = write(fd, p, nbytes)) <= 0) {
|
k = write(fd, p, nbytes);
|
||||||
|
if (k <= 0) {
|
||||||
|
|
||||||
if (k < 0 && errno == EINTR)
|
if (k < 0 && errno == EINTR)
|
||||||
continue;
|
continue;
|
||||||
@ -3503,6 +3533,22 @@ int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid) {
|
||||||
|
assert(fd >= 0);
|
||||||
|
|
||||||
|
/* Under the assumption that we are running privileged we
|
||||||
|
* first change the access mode and only then hand out
|
||||||
|
* ownership to avoid a window where access is too open. */
|
||||||
|
|
||||||
|
if (fchmod(fd, mode) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
if (fchown(fd, uid, gid) < 0)
|
||||||
|
return -errno;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
|
cpu_set_t* cpu_set_malloc(unsigned *ncpus) {
|
||||||
cpu_set_t *r;
|
cpu_set_t *r;
|
||||||
unsigned n = 1024;
|
unsigned n = 1024;
|
||||||
@ -3860,7 +3906,7 @@ char **replace_env_argv(char **argv, char **env) {
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
int columns(void) {
|
unsigned columns(void) {
|
||||||
static __thread int parsed_columns = 0;
|
static __thread int parsed_columns = 0;
|
||||||
const char *e;
|
const char *e;
|
||||||
|
|
||||||
@ -3903,38 +3949,41 @@ int running_in_chroot(void) {
|
|||||||
a.st_ino != b.st_ino;
|
a.st_ino != b.st_ino;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ellipsize(const char *s, unsigned length, unsigned percent) {
|
char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent) {
|
||||||
size_t l, x;
|
size_t x;
|
||||||
char *r;
|
char *r;
|
||||||
|
|
||||||
assert(s);
|
assert(s);
|
||||||
assert(percent <= 100);
|
assert(percent <= 100);
|
||||||
assert(length >= 3);
|
assert(new_length >= 3);
|
||||||
|
|
||||||
l = strlen(s);
|
if (old_length <= 3 || old_length <= new_length)
|
||||||
|
return strndup(s, old_length);
|
||||||
|
|
||||||
if (l <= 3 || l <= length)
|
r = new0(char, new_length+1);
|
||||||
return strdup(s);
|
if (!r)
|
||||||
|
|
||||||
if (!(r = new0(char, length+1)))
|
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
x = (length * percent) / 100;
|
x = (new_length * percent) / 100;
|
||||||
|
|
||||||
if (x > length - 3)
|
if (x > new_length - 3)
|
||||||
x = length - 3;
|
x = new_length - 3;
|
||||||
|
|
||||||
memcpy(r, s, x);
|
memcpy(r, s, x);
|
||||||
r[x] = '.';
|
r[x] = '.';
|
||||||
r[x+1] = '.';
|
r[x+1] = '.';
|
||||||
r[x+2] = '.';
|
r[x+2] = '.';
|
||||||
memcpy(r + x + 3,
|
memcpy(r + x + 3,
|
||||||
s + l - (length - x - 3),
|
s + old_length - (new_length - x - 3),
|
||||||
length - x - 3);
|
new_length - x - 3);
|
||||||
|
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *ellipsize(const char *s, size_t length, unsigned percent) {
|
||||||
|
return ellipsize_mem(s, strlen(s), length, percent);
|
||||||
|
}
|
||||||
|
|
||||||
int touch(const char *path) {
|
int touch(const char *path) {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
@ -4270,7 +4319,7 @@ const char *default_term_for_tty(const char *tty) {
|
|||||||
return term;
|
return term;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool dirent_is_file(struct dirent *de) {
|
bool dirent_is_file(const struct dirent *de) {
|
||||||
assert(de);
|
assert(de);
|
||||||
|
|
||||||
if (ignore_file(de->d_name))
|
if (ignore_file(de->d_name))
|
||||||
@ -4284,6 +4333,15 @@ bool dirent_is_file(struct dirent *de) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
|
||||||
|
assert(de);
|
||||||
|
|
||||||
|
if (!dirent_is_file(de))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return endswith(de->d_name, suffix);
|
||||||
|
}
|
||||||
|
|
||||||
void execute_directory(const char *directory, DIR *d, char *argv[]) {
|
void execute_directory(const char *directory, DIR *d, char *argv[]) {
|
||||||
DIR *_d = NULL;
|
DIR *_d = NULL;
|
||||||
struct dirent *de;
|
struct dirent *de;
|
||||||
@ -4456,6 +4514,98 @@ void parse_syslog_priority(char **p, int *priority) {
|
|||||||
*p += k;
|
*p += k;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void skip_syslog_pid(char **buf) {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
assert(buf);
|
||||||
|
assert(*buf);
|
||||||
|
|
||||||
|
p = *buf;
|
||||||
|
|
||||||
|
if (*p != '[')
|
||||||
|
return;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
p += strspn(p, "0123456789");
|
||||||
|
|
||||||
|
if (*p != ']')
|
||||||
|
return;
|
||||||
|
|
||||||
|
p++;
|
||||||
|
|
||||||
|
*buf = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
void skip_syslog_date(char **buf) {
|
||||||
|
enum {
|
||||||
|
LETTER,
|
||||||
|
SPACE,
|
||||||
|
NUMBER,
|
||||||
|
SPACE_OR_NUMBER,
|
||||||
|
COLON
|
||||||
|
} sequence[] = {
|
||||||
|
LETTER, LETTER, LETTER,
|
||||||
|
SPACE,
|
||||||
|
SPACE_OR_NUMBER, NUMBER,
|
||||||
|
SPACE,
|
||||||
|
SPACE_OR_NUMBER, NUMBER,
|
||||||
|
COLON,
|
||||||
|
SPACE_OR_NUMBER, NUMBER,
|
||||||
|
COLON,
|
||||||
|
SPACE_OR_NUMBER, NUMBER,
|
||||||
|
SPACE
|
||||||
|
};
|
||||||
|
|
||||||
|
char *p;
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
assert(buf);
|
||||||
|
assert(*buf);
|
||||||
|
|
||||||
|
p = *buf;
|
||||||
|
|
||||||
|
for (i = 0; i < ELEMENTSOF(sequence); i++, p++) {
|
||||||
|
|
||||||
|
if (!*p)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (sequence[i]) {
|
||||||
|
|
||||||
|
case SPACE:
|
||||||
|
if (*p != ' ')
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case SPACE_OR_NUMBER:
|
||||||
|
if (*p == ' ')
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* fall through */
|
||||||
|
|
||||||
|
case NUMBER:
|
||||||
|
if (*p < '0' || *p > '9')
|
||||||
|
return;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case LETTER:
|
||||||
|
if (!(*p >= 'A' && *p <= 'Z') &&
|
||||||
|
!(*p >= 'a' && *p <= 'z'))
|
||||||
|
return;
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case COLON:
|
||||||
|
if (*p != ':')
|
||||||
|
return;
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*buf = p;
|
||||||
|
}
|
||||||
|
|
||||||
int have_effective_cap(int value) {
|
int have_effective_cap(int value) {
|
||||||
cap_t cap;
|
cap_t cap;
|
||||||
cap_flag_value_t fv;
|
cap_flag_value_t fv;
|
||||||
@ -4675,21 +4825,6 @@ int vt_disallocate(const char *name) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int file_is_conf(const struct dirent *d, const char *suffix) {
|
|
||||||
assert(d);
|
|
||||||
|
|
||||||
if (ignore_file(d->d_name))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (d->d_type != DT_REG &&
|
|
||||||
d->d_type != DT_LNK &&
|
|
||||||
d->d_type != DT_UNKNOWN)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return endswith(d->d_name, suffix);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int files_add(Hashmap *h, const char *path, const char *suffix) {
|
static int files_add(Hashmap *h, const char *path, const char *suffix) {
|
||||||
DIR *dir;
|
DIR *dir;
|
||||||
struct dirent buffer, *de;
|
struct dirent buffer, *de;
|
||||||
@ -4715,7 +4850,7 @@ static int files_add(Hashmap *h, const char *path, const char *suffix) {
|
|||||||
if (!de)
|
if (!de)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (!file_is_conf(de, suffix))
|
if (!dirent_is_file_with_suffix(de, suffix))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (asprintf(&p, "%s/%s", path, de->d_name) < 0) {
|
if (asprintf(&p, "%s/%s", path, de->d_name) < 0) {
|
||||||
@ -5066,21 +5201,27 @@ int symlink_or_copy_atomic(const char *from, const char *to) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int audit_session_from_pid(pid_t pid, uint32_t *id) {
|
int audit_session_from_pid(pid_t pid, uint32_t *id) {
|
||||||
char *p, *s;
|
char *s;
|
||||||
uint32_t u;
|
uint32_t u;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(pid >= 1);
|
|
||||||
assert(id);
|
assert(id);
|
||||||
|
|
||||||
if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
|
if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
if (asprintf(&p, "/proc/%lu/sessionid", (unsigned long) pid) < 0)
|
if (pid == 0)
|
||||||
return -ENOMEM;
|
r = read_one_line_file("/proc/self/sessionid", &s);
|
||||||
|
else {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (asprintf(&p, "/proc/%lu/sessionid", (unsigned long) pid) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = read_one_line_file(p, &s);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
r = read_one_line_file(p, &s);
|
|
||||||
free(p);
|
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
@ -5097,6 +5238,51 @@ int audit_session_from_pid(pid_t pid, uint32_t *id) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int audit_loginuid_from_pid(pid_t pid, uid_t *uid) {
|
||||||
|
char *s;
|
||||||
|
uid_t u;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(uid);
|
||||||
|
|
||||||
|
/* Only use audit login uid if we are executed with sufficient
|
||||||
|
* capabilities so that pam_loginuid could do its job. If we
|
||||||
|
* are lacking the CAP_AUDIT_CONTROL capabality we most likely
|
||||||
|
* are being run in a container and /proc/self/loginuid is
|
||||||
|
* useless since it probably contains a uid of the host
|
||||||
|
* system. */
|
||||||
|
|
||||||
|
if (have_effective_cap(CAP_AUDIT_CONTROL) <= 0)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
if (pid == 0)
|
||||||
|
r = read_one_line_file("/proc/self/loginuid", &s);
|
||||||
|
else {
|
||||||
|
char *p;
|
||||||
|
|
||||||
|
if (asprintf(&p, "/proc/%lu/loginuid", (unsigned long) pid) < 0)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
r = read_one_line_file(p, &s);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
r = parse_uid(s, &u);
|
||||||
|
free(s);
|
||||||
|
|
||||||
|
if (r < 0)
|
||||||
|
return r;
|
||||||
|
|
||||||
|
if (u == (uid_t) -1)
|
||||||
|
return -ENOENT;
|
||||||
|
|
||||||
|
*uid = (uid_t) u;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool display_is_local(const char *display) {
|
bool display_is_local(const char *display) {
|
||||||
assert(display);
|
assert(display);
|
||||||
|
|
||||||
@ -5704,6 +5890,24 @@ int strdup_or_null(const char *a, char **b) {
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int prot_from_flags(int flags) {
|
||||||
|
|
||||||
|
switch (flags & O_ACCMODE) {
|
||||||
|
|
||||||
|
case O_RDONLY:
|
||||||
|
return PROT_READ;
|
||||||
|
|
||||||
|
case O_WRONLY:
|
||||||
|
return PROT_WRITE;
|
||||||
|
|
||||||
|
case O_RDWR:
|
||||||
|
return PROT_READ|PROT_WRITE;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
unsigned long cap_last_cap(void) {
|
unsigned long cap_last_cap(void) {
|
||||||
static __thread unsigned long saved;
|
static __thread unsigned long saved;
|
||||||
static __thread bool valid = false;
|
static __thread bool valid = false;
|
||||||
|
20
src/util.h
20
src/util.h
@ -248,8 +248,9 @@ int parent_of_path(const char *path, char **parent);
|
|||||||
|
|
||||||
int rmdir_parents(const char *path, const char *stop);
|
int rmdir_parents(const char *path, const char *stop);
|
||||||
|
|
||||||
int get_process_name(pid_t pid, char **name);
|
int get_process_comm(pid_t pid, char **name);
|
||||||
int get_process_cmdline(pid_t pid, size_t max_length, char **line);
|
int get_process_cmdline(pid_t pid, size_t max_length, bool comm_fallback, char **line);
|
||||||
|
int get_process_exe(pid_t pid, char **name);
|
||||||
|
|
||||||
char hexchar(int x);
|
char hexchar(int x);
|
||||||
int unhexchar(char c);
|
int unhexchar(char c);
|
||||||
@ -274,7 +275,9 @@ bool path_equal(const char *a, const char *b);
|
|||||||
|
|
||||||
char *ascii_strlower(char *path);
|
char *ascii_strlower(char *path);
|
||||||
|
|
||||||
bool dirent_is_file(struct dirent *de);
|
bool dirent_is_file(const struct dirent *de);
|
||||||
|
bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix);
|
||||||
|
|
||||||
bool ignore_file(const char *filename);
|
bool ignore_file(const char *filename);
|
||||||
|
|
||||||
bool chars_intersect(const char *a, const char *b);
|
bool chars_intersect(const char *a, const char *b);
|
||||||
@ -363,6 +366,7 @@ int get_ctty_devnr(pid_t pid, dev_t *d);
|
|||||||
int get_ctty(pid_t, dev_t *_devnr, char **r);
|
int get_ctty(pid_t, dev_t *_devnr, char **r);
|
||||||
|
|
||||||
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
|
int chmod_and_chown(const char *path, mode_t mode, uid_t uid, gid_t gid);
|
||||||
|
int fchmod_and_fchown(int fd, mode_t mode, uid_t uid, gid_t gid);
|
||||||
|
|
||||||
int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
|
int rm_rf(const char *path, bool only_dirs, bool delete_root, bool honour_sticky);
|
||||||
|
|
||||||
@ -374,11 +378,12 @@ void status_vprintf(const char *format, va_list ap);
|
|||||||
void status_printf(const char *format, ...);
|
void status_printf(const char *format, ...);
|
||||||
void status_welcome(void);
|
void status_welcome(void);
|
||||||
|
|
||||||
int columns(void);
|
unsigned columns(void);
|
||||||
|
|
||||||
int running_in_chroot(void);
|
int running_in_chroot(void);
|
||||||
|
|
||||||
char *ellipsize(const char *s, unsigned length, unsigned percent);
|
char *ellipsize(const char *s, size_t length, unsigned percent);
|
||||||
|
char *ellipsize_mem(const char *s, size_t old_length, size_t new_length, unsigned percent);
|
||||||
|
|
||||||
int touch(const char *path);
|
int touch(const char *path);
|
||||||
|
|
||||||
@ -415,6 +420,8 @@ bool nulstr_contains(const char*nulstr, const char *needle);
|
|||||||
bool plymouth_running(void);
|
bool plymouth_running(void);
|
||||||
|
|
||||||
void parse_syslog_priority(char **p, int *priority);
|
void parse_syslog_priority(char **p, int *priority);
|
||||||
|
void skip_syslog_pid(char **buf);
|
||||||
|
void skip_syslog_date(char **buf);
|
||||||
|
|
||||||
int have_effective_cap(int value);
|
int have_effective_cap(int value);
|
||||||
|
|
||||||
@ -443,6 +450,7 @@ int hwclock_get_time(struct tm *tm);
|
|||||||
int hwclock_set_time(const struct tm *tm);
|
int hwclock_set_time(const struct tm *tm);
|
||||||
|
|
||||||
int audit_session_from_pid(pid_t pid, uint32_t *id);
|
int audit_session_from_pid(pid_t pid, uint32_t *id);
|
||||||
|
int audit_loginuid_from_pid(pid_t pid, uid_t *uid);
|
||||||
|
|
||||||
bool display_is_local(const char *display);
|
bool display_is_local(const char *display);
|
||||||
int socket_from_display(const char *display, char **path);
|
int socket_from_display(const char *display, char **path);
|
||||||
@ -506,6 +514,8 @@ extern char **saved_argv;
|
|||||||
|
|
||||||
bool kexec_loaded(void);
|
bool kexec_loaded(void);
|
||||||
|
|
||||||
|
int prot_from_flags(int flags);
|
||||||
|
|
||||||
unsigned long cap_last_cap(void);
|
unsigned long cap_last_cap(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
1
tmpfiles.d/Makefile
Symbolic link
1
tmpfiles.d/Makefile
Symbolic link
@ -0,0 +1 @@
|
|||||||
|
../src/Makefile
|
1
units/.gitignore
vendored
1
units/.gitignore
vendored
@ -1,3 +1,4 @@
|
|||||||
|
/systemd-journald.service
|
||||||
user@.service
|
user@.service
|
||||||
systemd-logind.service
|
systemd-logind.service
|
||||||
systemd-localed.service
|
systemd-localed.service
|
||||||
|
@ -16,7 +16,7 @@ Before=sockets.target syslog.target
|
|||||||
Wants=syslog.target
|
Wants=syslog.target
|
||||||
|
|
||||||
[Socket]
|
[Socket]
|
||||||
ListenDatagram=/dev/log
|
ListenDatagram=/run/systemd/syslog
|
||||||
SocketMode=0666
|
SocketMode=0666
|
||||||
PassCred=yes
|
PassCred=yes
|
||||||
|
|
||||||
|
24
units/systemd-journald.service.in
Normal file
24
units/systemd-journald.service.in
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# See systemd.special(7) for details
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Journal Service
|
||||||
|
DefaultDependencies=no
|
||||||
|
Requires=systemd-journald.socket
|
||||||
|
After=systemd-journald.socket
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
ExecStart=@rootlibexecdir@/systemd-journald
|
||||||
|
NotifyAccess=all
|
||||||
|
StandardOutput=null
|
||||||
|
#CapabilityBoundingSet=CAP_SYS_ADMIN CAP_SETUID CAP_SETGID
|
||||||
|
|
||||||
|
# Increase the default a bit in order to allow many simultaneous
|
||||||
|
# services being run since we keep one fd open per service.
|
||||||
|
LimitNOFILE=16384
|
24
units/systemd-journald.socket
Normal file
24
units/systemd-journald.socket
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# This file is part of systemd.
|
||||||
|
#
|
||||||
|
# systemd is free software; you can redistribute it and/or modify it
|
||||||
|
# under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
|
||||||
|
# See systemd.special(7) for details
|
||||||
|
|
||||||
|
[Unit]
|
||||||
|
Description=Journal Socket
|
||||||
|
DefaultDependencies=no
|
||||||
|
Before=sockets.target syslog.target
|
||||||
|
|
||||||
|
# Mount and swap units need this. If this socket unit is removed by an
|
||||||
|
# isolate request the mount and and swap units would be removed too,
|
||||||
|
# hence let's exclude this from isolate requests.
|
||||||
|
IgnoreOnIsolate=yes
|
||||||
|
|
||||||
|
[Socket]
|
||||||
|
ListenStream=/run/systemd/stdout
|
||||||
|
ListenDatagram=/run/systemd/native
|
||||||
|
ListenDatagram=/dev/log
|
||||||
|
SocketMode=0666
|
Loading…
Reference in New Issue
Block a user