Merge pull request #9147 from keszybz/runtime-enablement

Runtime enablement
This commit is contained in:
Lennart Poettering 2018-06-04 11:58:21 +02:00 committed by GitHub
commit 0be9b12be2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 98 additions and 133 deletions

View File

@ -570,19 +570,19 @@
<term><option>--runtime</option></term>
<listitem>
<para>When used with <command>enable</command>,
<command>disable</command>, <command>edit</command>,
(and related commands), make changes only temporarily, so
that they are lost on the next reboot. This will have the
effect that changes are not made in subdirectories of
<filename>/etc</filename> but in <filename>/run</filename>,
with identical immediate effects, however, since the latter
<para>When used with <command>set-property</command>, make changes only
temporarily, so that they are lost on the next reboot.</para>
<para>Similarily, when used with <command>enable</command>, <command>mask</command>,
<command>edit</command> and related commands, make temporary changes, which are lost on
the next reboot. Changes are not made in subdirectories of <filename>/etc</filename>, but
in <filename>/run</filename>. The immediate effect is identical, however since the latter
is lost on reboot, the changes are lost too.</para>
<para>Similarly, when used with
<command>set-property</command>, make changes only
temporarily, so that they are lost on the next
reboot.</para>
<para>Note: this option cannot be used with <command>disable</command>,
<command>unmask</command>, <command>preset</command>, or <command>preset-all</command>,
because those operations sometimes need to remove symlinks under <filename>/etc</filename>
to have the desired effect, which would cause a persistent change.</para>
</listitem>
</varlistentry>

View File

@ -1098,17 +1098,11 @@ static void destroy_bus(Manager *m, sd_bus **bus) {
}
void bus_done_api(Manager *m) {
assert(m);
if (m->api_bus)
destroy_bus(m, &m->api_bus);
destroy_bus(m, &m->api_bus);
}
void bus_done_system(Manager *m) {
assert(m);
if (m->system_bus)
destroy_bus(m, &m->system_bus);
destroy_bus(m, &m->system_bus);
}
void bus_done_private(Manager *m) {

View File

@ -212,7 +212,7 @@ int journal_file_set_offline(JournalFile *f, bool wait) {
if (!f->writable)
return -EPERM;
if (!(f->fd >= 0 && f->header))
if (f->fd < 0 || !f->header)
return -EINVAL;
/* An offlining journal is implicitly online and may modify f->header->state,
@ -269,7 +269,7 @@ static int journal_file_set_online(JournalFile *f) {
if (!f->writable)
return -EPERM;
if (!(f->fd >= 0 && f->header))
if (f->fd < 0 || !f->header)
return -EINVAL;
while (wait) {

View File

@ -894,16 +894,13 @@ static int find_symlinks_in_scope(
if (r > 0) {
/* We found symlinks in this dir? Yay! Let's see where precisely it is enabled. */
r = path_is_config(paths, *p, false);
if (r < 0)
return r;
if (r > 0) {
if (path_equal_ptr(*p, paths->persistent_config)) {
/* This is the best outcome, let's return it immediately. */
*state = UNIT_FILE_ENABLED;
return 1;
}
/* look for globally enablement of user units */
/* look for global enablement of user units */
if (scope == UNIT_FILE_USER && path_is_user_config_dir(*p)) {
*state = UNIT_FILE_ENABLED;
return 1;
@ -918,11 +915,7 @@ static int find_symlinks_in_scope(
enabled_at_all = true;
} else if (same_name_link) {
r = path_is_config(paths, *p, false);
if (r < 0)
return r;
if (r > 0)
if (path_equal_ptr(*p, paths->persistent_config))
same_name_link_config = true;
else {
r = path_is_runtime(paths, *p, false);
@ -1923,7 +1916,6 @@ static int install_context_mark_for_removal(
InstallContext *c,
const LookupPaths *paths,
Set **remove_symlinks_to,
const char *config_path,
UnitFileChange **changes,
size_t *n_changes) {
@ -1932,7 +1924,6 @@ static int install_context_mark_for_removal(
assert(c);
assert(paths);
assert(config_path);
/* Marks all items for removal */
@ -2042,7 +2033,7 @@ int unit_file_unmask(
size_t n_todo = 0, n_allocated = 0;
const char *config_path;
char **i;
bool dry_run;
bool dry_run = !!(flags & UNIT_FILE_DRY_RUN);
int r, q;
assert(scope >= 0);
@ -2052,73 +2043,71 @@ int unit_file_unmask(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
dry_run = !!(flags & UNIT_FILE_DRY_RUN);
STRV_FOREACH(i, files) {
_cleanup_free_ char *path = NULL;
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
return -EINVAL;
path = path_make_absolute(*i, config_path);
if (!path)
return -ENOMEM;
FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
_cleanup_free_ char *path = NULL;
r = null_or_empty_path(path);
if (r == -ENOENT)
continue;
if (r < 0)
return r;
if (r == 0)
continue;
path = path_make_absolute(*i, config_path);
if (!path)
return -ENOMEM;
if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
return -ENOMEM;
r = null_or_empty_path(path);
if (r == -ENOENT)
continue;
if (r < 0)
return r;
if (r == 0)
continue;
todo[n_todo] = strdup(*i);
if (!todo[n_todo])
return -ENOMEM;
if (!GREEDY_REALLOC0(todo, n_allocated, n_todo + 2))
return -ENOMEM;
n_todo++;
todo[n_todo] = strdup(*i);
if (!todo[n_todo])
return -ENOMEM;
n_todo++;
}
}
strv_uniq(todo);
r = 0;
STRV_FOREACH(i, todo) {
_cleanup_free_ char *path = NULL;
const char *rp;
FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
STRV_FOREACH(i, todo) {
_cleanup_free_ char *path = NULL;
const char *rp;
path = path_make_absolute(*i, config_path);
if (!path)
return -ENOMEM;
path = path_make_absolute(*i, config_path);
if (!path)
return -ENOMEM;
if (!dry_run && unlink(path) < 0) {
if (errno != ENOENT) {
if (r >= 0)
r = -errno;
unit_file_changes_add(changes, n_changes, -errno, path, NULL);
if (!dry_run && unlink(path) < 0) {
if (errno != ENOENT) {
if (r >= 0)
r = -errno;
unit_file_changes_add(changes, n_changes, -errno, path, NULL);
}
continue;
}
continue;
unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
rp = skip_root(&paths, path);
q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
if (q < 0)
return q;
}
unit_file_changes_add(changes, n_changes, UNIT_FILE_UNLINK, path, NULL);
rp = skip_root(&paths, path);
q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: path);
if (q < 0)
return q;
q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
if (r >= 0)
r = q;
}
q = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
if (r >= 0)
r = q;
return r;
}
@ -2510,6 +2499,7 @@ int unit_file_disable(
_cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(install_context_done) InstallContext c = {};
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
bool dry_run = !!(flags & UNIT_FILE_DRY_RUN);
const char *config_path;
char **i;
int r;
@ -2521,10 +2511,6 @@ int unit_file_disable(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
STRV_FOREACH(i, files) {
if (!unit_name_is_valid(*i, UNIT_NAME_ANY))
return -EINVAL;
@ -2534,11 +2520,17 @@ int unit_file_disable(
return r;
}
r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, config_path, changes, n_changes);
r = install_context_mark_for_removal(scope, &c, &paths, &remove_symlinks_to, changes, n_changes);
if (r < 0)
return r;
return remove_marked_symlinks(remove_symlinks_to, config_path, &paths, !!(flags & UNIT_FILE_DRY_RUN), changes, n_changes);
FOREACH_STRING(config_path, paths.runtime_config, paths.persistent_config) {
r = remove_marked_symlinks(remove_symlinks_to, config_path, &paths, dry_run, changes, n_changes);
if (r < 0)
return r;
}
return 0;
}
int unit_file_reenable(
@ -2922,45 +2914,45 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char
static int execute_preset(
UnitFileScope scope,
UnitFileFlags flags,
InstallContext *plus,
InstallContext *minus,
const LookupPaths *paths,
const char *config_path,
char **files,
UnitFilePresetMode mode,
bool force,
UnitFileChange **changes,
size_t *n_changes) {
int r;
const char *config_path;
bool force = !!(flags & UNIT_FILE_FORCE);
bool runtime = !!(flags & UNIT_FILE_RUNTIME);
int r = 0, q;
assert(plus);
assert(minus);
assert(paths);
assert(config_path);
if (mode != UNIT_FILE_PRESET_ENABLE_ONLY) {
_cleanup_set_free_free_ Set *remove_symlinks_to = NULL;
r = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, config_path, changes, n_changes);
if (r < 0)
return r;
q = install_context_mark_for_removal(scope, minus, paths, &remove_symlinks_to, changes, n_changes);
if (q < 0)
return q;
r = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
} else
r = 0;
FOREACH_STRING(config_path, paths->runtime_config, paths->persistent_config) {
q = remove_marked_symlinks(remove_symlinks_to, config_path, paths, false, changes, n_changes);
if (r == 0)
r = q;
}
}
if (mode != UNIT_FILE_PRESET_DISABLE_ONLY) {
int q;
/* Returns number of symlinks that where supposed to be installed. */
q = install_context_apply(scope, plus, paths, config_path, force, SEARCH_LOAD, changes, n_changes);
if (r >= 0) {
if (q < 0)
r = q;
else
r += q;
}
q = install_context_apply(scope, plus, paths,
runtime ? paths->runtime_config : paths->persistent_config,
force, SEARCH_LOAD, changes, n_changes);
if (r == 0)
r = q;
}
return r;
@ -3024,7 +3016,6 @@ int unit_file_preset(
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
_cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(presets_freep) Presets presets = {};
const char *config_path;
char **i;
int r;
@ -3036,10 +3027,6 @@ int unit_file_preset(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
r = read_presets(scope, root_dir, &presets);
if (r < 0)
return r;
@ -3050,7 +3037,7 @@ int unit_file_preset(
return r;
}
return execute_preset(scope, &plus, &minus, &paths, config_path, files, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
return execute_preset(scope, flags, &plus, &minus, &paths, files, mode, changes, n_changes);
}
int unit_file_preset_all(
@ -3064,7 +3051,6 @@ int unit_file_preset_all(
_cleanup_(install_context_done) InstallContext plus = {}, minus = {};
_cleanup_(lookup_paths_free) LookupPaths paths = {};
_cleanup_(presets_freep) Presets presets = {};
const char *config_path = NULL;
char **i;
int r;
@ -3076,10 +3062,6 @@ int unit_file_preset_all(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
r = read_presets(scope, root_dir, &presets);
if (r < 0)
return r;
@ -3097,7 +3079,6 @@ int unit_file_preset_all(
}
FOREACH_DIRENT(de, d, return -errno) {
if (!unit_name_is_valid(de->d_name, UNIT_NAME_ANY))
continue;
@ -3121,7 +3102,7 @@ int unit_file_preset_all(
}
}
return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
return execute_preset(scope, flags, &plus, &minus, &paths, NULL, mode, changes, n_changes);
}
static void unit_file_list_free_one(UnitFileList *f) {

View File

@ -233,7 +233,6 @@ static void release_busses(void) {
}
static void ask_password_agent_open_if_enabled(void) {
/* Open the password agent as a child process if necessary */
if (arg_dry_run)
@ -297,7 +296,6 @@ static int translate_bus_error_to_exit_status(int r, const sd_bus_error *error)
}
static bool install_client_side(void) {
/* Decides when to execute enable/disable/... operations
* client-side rather than server-side. */
@ -1612,7 +1610,6 @@ static int list_dependencies_print(const char *name, int level, unsigned int bra
}
static int list_dependencies_get_dependencies(sd_bus *bus, const char *name, char ***deps) {
struct DependencyStatusInfo {
char **dep[5];
} info = {};
@ -6497,7 +6494,6 @@ static int show_installation_targets(sd_bus *bus, const char *name) {
}
static int unit_is_enabled(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
bool enabled;
char **name;
@ -6998,7 +6994,6 @@ end:
}
static void systemctl_help(void) {
(void) pager_open(arg_no_pager, false);
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
@ -7256,7 +7251,6 @@ static void help_states(void) {
}
static int systemctl_parse_argv(int argc, char *argv[]) {
enum {
ARG_FAIL = 0x100,
ARG_REVERSE,
@ -7687,11 +7681,15 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
return -EINVAL;
}
if (arg_runtime && STRPTR_IN_SET(argv[optind], "disable", "unmask", "preset", "preset-all")) {
log_error("--runtime cannot be used with %s", argv[optind]);
return -EINVAL;
}
return 1;
}
static int halt_parse_argv(int argc, char *argv[]) {
enum {
ARG_HELP = 0x100,
ARG_HALT,
@ -7835,7 +7833,6 @@ static int parse_shutdown_time_spec(const char *t, usec_t *_u) {
}
static int shutdown_parse_argv(int argc, char *argv[]) {
enum {
ARG_HELP = 0x100,
ARG_NO_WALL
@ -7942,7 +7939,6 @@ static int shutdown_parse_argv(int argc, char *argv[]) {
}
static int telinit_parse_argv(int argc, char *argv[]) {
enum {
ARG_HELP = 0x100,
ARG_NO_WALL
@ -8029,7 +8025,6 @@ static int telinit_parse_argv(int argc, char *argv[]) {
}
static int runlevel_parse_argv(int argc, char *argv[]) {
enum {
ARG_HELP = 0x100,
};
@ -8131,7 +8126,6 @@ static int parse_argv(int argc, char *argv[]) {
#if HAVE_SYSV_COMPAT
_pure_ static int action_to_runlevel(void) {
static const char table[_ACTION_MAX] = {
[ACTION_HALT] = '0',
[ACTION_POWEROFF] = '0',
@ -8191,7 +8185,6 @@ static int talk_initctl(void) {
}
static int systemctl_main(int argc, char *argv[]) {
static const Verb verbs[] = {
{ "list-units", VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_units },
{ "list-unit-files", VERB_ANY, VERB_ANY, 0, list_unit_files },
@ -8267,7 +8260,6 @@ static int systemctl_main(int argc, char *argv[]) {
}
static int reload_with_fallback(void) {
/* First, try systemd via D-Bus. */
if (daemon_reload(0, NULL, NULL) >= 0)
return 0;
@ -8282,7 +8274,6 @@ static int reload_with_fallback(void) {
}
static int start_with_fallback(void) {
/* First, try systemd via D-Bus. */
if (start_unit(0, NULL, NULL) >= 0)
return 0;
@ -8296,7 +8287,6 @@ static int start_with_fallback(void) {
}
static int halt_now(enum action a) {
/* The kernel will automatically flush ATA disks and suchlike on reboot(), but the file systems need to be
* synce'd explicitly in advance. */
if (!arg_no_sync && !arg_dry_run)