Merge pull request #22071 from keszybz/xdg-autostart-logs
Improve logs in systemd-xdg-autostart-generator
This commit is contained in:
@@ -97,13 +97,13 @@ to create appropriate units for the autostart directory
|
||||
(`systemd-xdg-autostart-generator`).
|
||||
Desktop Environments can opt-in to using this by starting
|
||||
`xdg-desktop-autostart.target`. The systemd generator correctly handles
|
||||
`OnlyShowIn=` and `NotShowin=`. It also handles the KDE and GNOME specific
|
||||
`X-KDE-autostart-condition=` and `AutostartCondition=` by using desktop
|
||||
environment provided binaries in an `ExecCondition=` line.
|
||||
`OnlyShowIn=` and `NotShowIn=`. It also handles the KDE and GNOME specific
|
||||
`X-KDE-autostart-condition=` and `AutostartCondition=` by using desktop-environment-provided
|
||||
binaries in an `ExecCondition=` line.
|
||||
|
||||
However, this generator is somewhat limited in what it supports. For example,
|
||||
all generated units will have `After=graphical-session.target` set on them,
|
||||
it may therefore not be useful to start session services.
|
||||
and therefore may not be useful to start session services.
|
||||
|
||||
Desktop files can be marked to be explicitly excluded from the generator using the line
|
||||
`X-systemd-skip=true`. This should be set if an application provides its own
|
||||
|
||||
@@ -44,38 +44,42 @@ static int enumerate_xdg_autostart(Hashmap *all_services) {
|
||||
STRV_FOREACH(path, autostart_dirs) {
|
||||
_cleanup_closedir_ DIR *d = NULL;
|
||||
|
||||
log_debug("Scanning autostart directory \"%s\"…", *path);
|
||||
d = opendir(*path);
|
||||
if (!d) {
|
||||
if (errno != ENOENT)
|
||||
log_warning_errno(errno, "Opening %s failed, ignoring: %m", *path);
|
||||
log_full_errno(errno == ENOENT ? LOG_DEBUG : LOG_WARNING, errno,
|
||||
"Opening %s failed, ignoring: %m", *path);
|
||||
continue;
|
||||
}
|
||||
|
||||
FOREACH_DIRENT(de, d, log_warning_errno(errno, "Failed to enumerate directory %s, ignoring: %m", *path)) {
|
||||
_cleanup_free_ char *fpath = NULL, *name = NULL;
|
||||
_cleanup_(xdg_autostart_service_freep) XdgAutostartService *service = NULL;
|
||||
struct stat st;
|
||||
|
||||
if (fstatat(dirfd(d), de->d_name, &st, 0) < 0) {
|
||||
log_warning_errno(errno, "stat() failed on %s/%s, ignoring: %m", *path, de->d_name);
|
||||
log_warning_errno(errno, "%s/%s: stat() failed, ignoring: %m", *path, de->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!S_ISREG(st.st_mode))
|
||||
if (!S_ISREG(st.st_mode)) {
|
||||
log_debug("%s/%s: not a regular file, ignoring.", *path, de->d_name);
|
||||
continue;
|
||||
}
|
||||
|
||||
name = xdg_autostart_service_translate_name(de->d_name);
|
||||
_cleanup_free_ char *name = xdg_autostart_service_translate_name(de->d_name);
|
||||
if (!name)
|
||||
return log_oom();
|
||||
|
||||
if (hashmap_contains(all_services, name))
|
||||
if (hashmap_contains(all_services, name)) {
|
||||
log_debug("%s/%s: we have already seen \"%s\", ignoring.",
|
||||
*path, de->d_name, name);
|
||||
continue;
|
||||
}
|
||||
|
||||
fpath = path_join(*path, de->d_name);
|
||||
_cleanup_free_ char *fpath = path_join(*path, de->d_name);
|
||||
if (!fpath)
|
||||
return log_oom();
|
||||
|
||||
service = xdg_autostart_service_parse_desktop(fpath);
|
||||
_cleanup_(xdg_autostart_service_freep) XdgAutostartService *service =
|
||||
xdg_autostart_service_parse_desktop(fpath);
|
||||
if (!service)
|
||||
return log_oom();
|
||||
service->name = TAKE_PTR(name);
|
||||
|
||||
@@ -470,6 +470,7 @@ int xdg_autostart_format_exec_start(
|
||||
}
|
||||
|
||||
static int xdg_autostart_generate_desktop_condition(
|
||||
const XdgAutostartService *service,
|
||||
FILE *f,
|
||||
const char *test_binary,
|
||||
const char *condition) {
|
||||
@@ -483,7 +484,8 @@ static int xdg_autostart_generate_desktop_condition(
|
||||
r = find_executable(test_binary, &gnome_autostart_condition_path);
|
||||
if (r < 0) {
|
||||
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"%s not found: %m", test_binary);
|
||||
"%s: ExecCondition executable %s not found, unit will not be started automatically: %m",
|
||||
service->path, test_binary);
|
||||
fprintf(f, "# ExecCondition using %s skipped due to missing binary.\n", test_binary);
|
||||
return r;
|
||||
}
|
||||
@@ -492,6 +494,9 @@ static int xdg_autostart_generate_desktop_condition(
|
||||
if (!e_autostart_condition)
|
||||
return log_oom();
|
||||
|
||||
log_debug("%s: ExecCondition converted to %s --condition \"%s\"…",
|
||||
service->path, gnome_autostart_condition_path, e_autostart_condition);
|
||||
|
||||
fprintf(f,
|
||||
"ExecCondition=%s --condition \"%s\"\n",
|
||||
gnome_autostart_condition_path,
|
||||
@@ -502,7 +507,7 @@ static int xdg_autostart_generate_desktop_condition(
|
||||
}
|
||||
|
||||
int xdg_autostart_service_generate_unit(
|
||||
XdgAutostartService *service,
|
||||
const XdgAutostartService *service,
|
||||
const char *dest) {
|
||||
|
||||
_cleanup_free_ char *path_escaped = NULL, *exec_start = NULL, *unit = NULL;
|
||||
@@ -513,23 +518,23 @@ int xdg_autostart_service_generate_unit(
|
||||
|
||||
/* Nothing to do for hidden services. */
|
||||
if (service->hidden) {
|
||||
log_debug("Not generating service for XDG autostart %s, it is hidden.", service->name);
|
||||
log_debug("%s: not generating unit, entry is hidden.", service->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (service->systemd_skip) {
|
||||
log_debug("Not generating service for XDG autostart %s, should be skipped by generator.", service->name);
|
||||
log_debug("%s: not generating unit, marked as skipped by generator.", service->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Nothing to do if type is not Application. */
|
||||
if (!streq_ptr(service->type, "Application")) {
|
||||
log_debug("Not generating service for XDG autostart %s, only Type=Application is supported.", service->name);
|
||||
log_debug("%s: not generating unit, Type=%s is not supported.", service->path, service->type);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!service->exec_string) {
|
||||
log_warning("Not generating service for XDG autostart %s, it is has no Exec= line.", service->name);
|
||||
log_warning("%s: not generating unit, no Exec= line.", service->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -539,24 +544,21 @@ int xdg_autostart_service_generate_unit(
|
||||
r = find_executable(service->try_exec, NULL);
|
||||
if (r < 0) {
|
||||
log_full_errno(r == -ENOENT ? LOG_DEBUG : LOG_WARNING, r,
|
||||
"Not generating service for XDG autostart %s, could not find TryExec= binary %s: %m",
|
||||
service->name, service->try_exec);
|
||||
"%s: not generating unit, could not find TryExec= binary %s: %m",
|
||||
service->path, service->try_exec);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
r = xdg_autostart_format_exec_start(service->exec_string, &exec_start);
|
||||
if (r < 0) {
|
||||
log_warning_errno(r,
|
||||
"Not generating service for XDG autostart %s, error parsing Exec= line: %m",
|
||||
service->name);
|
||||
log_warning_errno(r, "%s: not generating unit, error parsing Exec= line: %m", service->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (service->gnome_autostart_phase) {
|
||||
/* There is no explicit value for the "Application" phase. */
|
||||
log_debug("Not generating service for XDG autostart %s, startup phases are not supported.",
|
||||
service->name);
|
||||
log_debug("%s: not generating unit, startup phases are not supported.", service->path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -570,7 +572,7 @@ int xdg_autostart_service_generate_unit(
|
||||
|
||||
f = fopen(unit, "wxe");
|
||||
if (!f)
|
||||
return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
|
||||
return log_error_errno(errno, "%s: failed to create unit file %s: %m", service->path, unit);
|
||||
|
||||
fprintf(f,
|
||||
"# Automatically generated by systemd-xdg-autostart-generator\n\n"
|
||||
@@ -635,19 +637,18 @@ int xdg_autostart_service_generate_unit(
|
||||
e_not_show_in);
|
||||
}
|
||||
|
||||
r = xdg_autostart_generate_desktop_condition(f,
|
||||
r = xdg_autostart_generate_desktop_condition(service, f,
|
||||
"gnome-systemd-autostart-condition",
|
||||
service->autostart_condition);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = xdg_autostart_generate_desktop_condition(f,
|
||||
r = xdg_autostart_generate_desktop_condition(service, f,
|
||||
"kde-systemd-start-condition",
|
||||
service->kde_autostart_condition);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
(void) generator_add_symlink(dest, "xdg-desktop-autostart.target", "wants", service->name);
|
||||
|
||||
return 0;
|
||||
log_debug("%s: symlinking %s in xdg-desktop-autostart.target/.wants…", service->path, service->name);
|
||||
return generator_add_symlink(dest, "xdg-desktop-autostart.target", "wants", service->name);
|
||||
}
|
||||
|
||||
@@ -26,7 +26,6 @@ typedef struct XdgAutostartService {
|
||||
|
||||
} XdgAutostartService;
|
||||
|
||||
|
||||
XdgAutostartService * xdg_autostart_service_free(XdgAutostartService *s);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(XdgAutostartService*, xdg_autostart_service_free);
|
||||
|
||||
@@ -34,4 +33,4 @@ char *xdg_autostart_service_translate_name(const char *name);
|
||||
int xdg_autostart_format_exec_start(const char *exec, char **ret_exec_start);
|
||||
|
||||
XdgAutostartService *xdg_autostart_service_parse_desktop(const char *path);
|
||||
int xdg_autostart_service_generate_unit(XdgAutostartService *service, const char *dest);
|
||||
int xdg_autostart_service_generate_unit(const XdgAutostartService *service, const char *dest);
|
||||
|
||||
Reference in New Issue
Block a user