Merge pull request #19870 from keszybz/install-foo-again

Tweak the install logic again
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2021-06-10 18:56:03 +02:00 committed by GitHub
commit c3988f36d3
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 76 additions and 53 deletions

View file

@ -2272,7 +2272,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
UnitFileChange *changes = NULL;
size_t n_changes = 0;
Manager *m = userdata;
UnitFilePresetMode mm;
UnitFilePresetMode preset_mode;
int runtime, force, r;
UnitFileFlags flags;
const char *mode;
@ -2291,10 +2291,10 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
flags = unit_file_bools_to_flags(runtime, force);
if (isempty(mode))
mm = UNIT_FILE_PRESET_FULL;
preset_mode = UNIT_FILE_PRESET_FULL;
else {
mm = unit_file_preset_mode_from_string(mode);
if (mm < 0)
preset_mode = unit_file_preset_mode_from_string(mode);
if (preset_mode < 0)
return -EINVAL;
}
@ -2304,7 +2304,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
r = unit_file_preset(m->unit_file_scope, flags, NULL, l, mm, &changes, &n_changes);
r = unit_file_preset(m->unit_file_scope, flags, NULL, l, preset_mode, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);
@ -2436,7 +2436,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
UnitFileChange *changes = NULL;
size_t n_changes = 0;
Manager *m = userdata;
UnitFilePresetMode mm;
UnitFilePresetMode preset_mode;
const char *mode;
UnitFileFlags flags;
int force, runtime, r;
@ -2455,10 +2455,10 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
flags = unit_file_bools_to_flags(runtime, force);
if (isempty(mode))
mm = UNIT_FILE_PRESET_FULL;
preset_mode = UNIT_FILE_PRESET_FULL;
else {
mm = unit_file_preset_mode_from_string(mode);
if (mm < 0)
preset_mode = unit_file_preset_mode_from_string(mode);
if (preset_mode < 0)
return -EINVAL;
}
@ -2468,7 +2468,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata,
if (r == 0)
return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */
r = unit_file_preset_all(m->unit_file_scope, flags, NULL, mm, &changes, &n_changes);
r = unit_file_preset_all(m->unit_file_scope, flags, NULL, preset_mode, &changes, &n_changes);
if (r < 0)
return install_error(error, r, changes, n_changes);

View file

@ -269,7 +269,6 @@ int unit_file_changes_add(
_cleanup_free_ char *p = NULL, *s = NULL;
UnitFileChange *c;
assert(path);
assert(!changes == !n_changes);
if (type_or_errno >= 0)
@ -285,11 +284,13 @@ int unit_file_changes_add(
return -ENOMEM;
*changes = c;
p = strdup(path);
if (!p)
return -ENOMEM;
if (path) {
p = strdup(path);
if (!p)
return -ENOMEM;
path_simplify(p);
path_simplify(p);
}
if (source) {
s = strdup(source);
@ -355,6 +356,10 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
log_warning("Unit %s is added as a dependency to a non-existent unit %s.",
changes[i].source, changes[i].path);
break;
case UNIT_FILE_AUXILIARY_FAILED:
if (!quiet)
log_warning("Failed to enable auxiliary unit %s, ignoring.", changes[i].source);
break;
case -EEXIST:
if (changes[i].source)
log_error_errno(changes[i].type_or_errno,
@ -377,8 +382,8 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
logged = true;
break;
case -EIDRM:
log_error_errno(changes[i].type_or_errno, "Failed to %s unit, unit %s is a non-template unit.",
verb, changes[i].path);
log_error_errno(changes[i].type_or_errno, "Failed to %s %s, destination unit %s is a non-template unit.",
verb, changes[i].source, changes[i].path);
logged = true;
break;
case -EUCLEAN:
@ -1843,6 +1848,7 @@ static int install_info_symlink_alias(
static int install_info_symlink_wants(
UnitFileScope scope,
UnitFileFlags file_flags,
UnitFileInstallInfo *i,
const LookupPaths *paths,
const char *config_path,
@ -1910,8 +1916,16 @@ static int install_info_symlink_wants(
return q;
if (!unit_name_is_valid(dst, valid_dst_type)) {
/* Generate a proper error here: EUCLEAN if the name is generally bad,
* EIDRM if the template status doesn't match. */
/* Generate a proper error here: EUCLEAN if the name is generally bad, EIDRM if the
* template status doesn't match. If we are doing presets don't bother reporting the
* error. This also covers cases like 'systemctl preset serial-getty@.service', which
* has no DefaultInstance, so there is nothing we can do. At the same time,
* 'systemctl enable serial-getty@.service' should fail, the user should specify an
* instance like in 'systemctl enable serial-getty@ttyS0.service'.
*/
if (file_flags & UNIT_FILE_IGNORE_AUXILIARY_FAILURE)
continue;
if (unit_name_is_valid(dst, UNIT_NAME_ANY)) {
unit_file_changes_add(changes, n_changes, -EIDRM, dst, n);
r = -EIDRM;
@ -1969,10 +1983,10 @@ static int install_info_symlink_link(
static int install_info_apply(
UnitFileScope scope,
UnitFileFlags file_flags,
UnitFileInstallInfo *i,
const LookupPaths *paths,
const char *config_path,
bool force,
UnitFileChange **changes,
size_t *n_changes) {
@ -1985,13 +1999,15 @@ static int install_info_apply(
if (i->type != UNIT_FILE_TYPE_REGULAR)
return 0;
bool force = file_flags & UNIT_FILE_FORCE;
r = install_info_symlink_alias(i, paths, config_path, force, changes, n_changes);
q = install_info_symlink_wants(scope, i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
q = install_info_symlink_wants(scope, file_flags, i, paths, config_path, i->wanted_by, ".wants/", changes, n_changes);
if (r == 0)
r = q;
q = install_info_symlink_wants(scope, i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
q = install_info_symlink_wants(scope, file_flags, i, paths, config_path, i->required_by, ".requires/", changes, n_changes);
if (r == 0)
r = q;
@ -2005,10 +2021,10 @@ static int install_info_apply(
static int install_context_apply(
UnitFileScope scope,
UnitFileFlags file_flags,
InstallContext *c,
const LookupPaths *paths,
const char *config_path,
bool force,
SearchFlags flags,
UnitFileChange **changes,
size_t *n_changes) {
@ -2037,6 +2053,13 @@ static int install_context_apply(
q = install_info_traverse(scope, c, paths, i, flags, NULL);
if (q < 0) {
if (i->auxiliary) {
q = unit_file_changes_add(changes, n_changes, UNIT_FILE_AUXILIARY_FAILED, NULL, i->name);
if (q < 0)
return q;
continue;
}
unit_file_changes_add(changes, n_changes, q, i->name, NULL);
return q;
}
@ -2055,7 +2078,7 @@ static int install_context_apply(
if (i->type != UNIT_FILE_TYPE_REGULAR)
continue;
q = install_info_apply(scope, i, paths, config_path, force, changes, n_changes);
q = install_info_apply(scope, file_flags, i, paths, config_path, changes, n_changes);
if (r >= 0) {
if (q < 0)
r = q;
@ -2528,7 +2551,7 @@ int unit_file_revert(
int unit_file_add_dependency(
UnitFileScope scope,
UnitFileFlags flags,
UnitFileFlags file_flags,
const char *root_dir,
char **files,
const char *target,
@ -2557,7 +2580,7 @@ int unit_file_add_dependency(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
config_path = (file_flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
@ -2593,12 +2616,13 @@ int unit_file_add_dependency(
return -ENOMEM;
}
return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
return install_context_apply(scope, file_flags, &c, &paths, config_path,
SEARCH_FOLLOW_CONFIG_SYMLINKS, changes, n_changes);
}
int unit_file_enable(
UnitFileScope scope,
UnitFileFlags flags,
UnitFileFlags file_flags,
const char *root_dir,
char **files,
UnitFileChange **changes,
@ -2618,7 +2642,7 @@ int unit_file_enable(
if (r < 0)
return r;
config_path = config_path_from_flags(&paths, flags);
config_path = config_path_from_flags(&paths, file_flags);
if (!config_path)
return -ENXIO;
@ -2636,7 +2660,7 @@ int unit_file_enable(
is useful to determine whether the passed files had any
installation data at all. */
return install_context_apply(scope, &c, &paths, config_path, !!(flags & UNIT_FILE_FORCE), SEARCH_LOAD, changes, n_changes);
return install_context_apply(scope, file_flags, &c, &paths, config_path, SEARCH_LOAD, changes, n_changes);
}
int unit_file_disable(
@ -3166,13 +3190,13 @@ int unit_file_query_preset(UnitFileScope scope, const char *root_dir, const char
static int execute_preset(
UnitFileScope scope,
UnitFileFlags file_flags,
InstallContext *plus,
InstallContext *minus,
const LookupPaths *paths,
const char *config_path,
char **files,
UnitFilePresetMode mode,
bool force,
UnitFileChange **changes,
size_t *n_changes) {
@ -3198,7 +3222,9 @@ static int execute_preset(
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);
q = install_context_apply(scope,
file_flags | UNIT_FILE_IGNORE_AUXILIARY_FAILURE,
plus, paths, config_path, SEARCH_LOAD, changes, n_changes);
if (r >= 0) {
if (q < 0)
r = q;
@ -3266,7 +3292,7 @@ static int preset_prepare_one(
int unit_file_preset(
UnitFileScope scope,
UnitFileFlags flags,
UnitFileFlags file_flags,
const char *root_dir,
char **files,
UnitFilePresetMode mode,
@ -3288,7 +3314,7 @@ int unit_file_preset(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
config_path = (file_flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
@ -3302,12 +3328,12 @@ 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, file_flags, &plus, &minus, &paths, config_path, files, mode, changes, n_changes);
}
int unit_file_preset_all(
UnitFileScope scope,
UnitFileFlags flags,
UnitFileFlags file_flags,
const char *root_dir,
UnitFilePresetMode mode,
UnitFileChange **changes,
@ -3328,7 +3354,7 @@ int unit_file_preset_all(
if (r < 0)
return r;
config_path = (flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
config_path = (file_flags & UNIT_FILE_RUNTIME) ? paths.runtime_config : paths.persistent_config;
if (!config_path)
return -ENXIO;
@ -3358,22 +3384,16 @@ int unit_file_preset_all(
if (!IN_SET(de->d_type, DT_LNK, DT_REG))
continue;
/* we don't pass changes[] in, because we want to handle errors on our own */
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, &presets, NULL, 0);
if (r == -ERFKILL)
r = unit_file_changes_add(changes, n_changes,
UNIT_FILE_IS_MASKED, de->d_name, NULL);
else if (r == -ENOLINK)
r = unit_file_changes_add(changes, n_changes,
UNIT_FILE_IS_DANGLING, de->d_name, NULL);
else if (r == -EADDRNOTAVAIL) /* Ignore generated/transient units when applying preset */
continue;
if (r < 0)
r = preset_prepare_one(scope, &plus, &minus, &paths, de->d_name, &presets, changes, n_changes);
if (r < 0 &&
!IN_SET(r, -EEXIST, -ERFKILL, -EADDRNOTAVAIL, -EIDRM, -EUCLEAN, -ELOOP, -ENOENT))
/* Ignore generated/transient/missing/invalid units when applying preset, propagate other errors.
* Coordinate with unit_file_dump_changes() above. */
return r;
}
}
return execute_preset(scope, &plus, &minus, &paths, config_path, NULL, mode, !!(flags & UNIT_FILE_FORCE), changes, n_changes);
return execute_preset(scope, file_flags, &plus, &minus, &paths, config_path, NULL, mode, changes, n_changes);
}
static UnitFileList* unit_file_list_free_one(UnitFileList *f) {
@ -3493,6 +3513,7 @@ static const char* const unit_file_change_type_table[_UNIT_FILE_CHANGE_TYPE_MAX]
[UNIT_FILE_IS_MASKED] = "masked",
[UNIT_FILE_IS_DANGLING] = "dangling",
[UNIT_FILE_DESTINATION_NOT_PRESENT] = "destination not present",
[UNIT_FILE_AUXILIARY_FAILED] = "auxiliary unit failed",
};
DEFINE_STRING_TABLE_LOOKUP(unit_file_change_type, int);

View file

@ -33,15 +33,17 @@ enum {
UNIT_FILE_IS_MASKED,
UNIT_FILE_IS_DANGLING,
UNIT_FILE_DESTINATION_NOT_PRESENT,
UNIT_FILE_AUXILIARY_FAILED,
_UNIT_FILE_CHANGE_TYPE_MAX,
_UNIT_FILE_CHANGE_TYPE_INVALID = -EINVAL,
};
enum UnitFileFlags {
UNIT_FILE_RUNTIME = 1 << 0, /* Public API via DBUS, do not change */
UNIT_FILE_FORCE = 1 << 1, /* Public API via DBUS, do not change */
UNIT_FILE_PORTABLE = 1 << 2, /* Public API via DBUS, do not change */
UNIT_FILE_DRY_RUN = 1 << 3,
UNIT_FILE_RUNTIME = 1 << 0, /* Public API via DBUS, do not change */
UNIT_FILE_FORCE = 1 << 1, /* Public API via DBUS, do not change */
UNIT_FILE_PORTABLE = 1 << 2, /* Public API via DBUS, do not change */
UNIT_FILE_DRY_RUN = 1 << 3,
UNIT_FILE_IGNORE_AUXILIARY_FAILURE = 1 << 4,
_UNIT_FILE_FLAGS_MASK_PUBLIC = UNIT_FILE_RUNTIME|UNIT_FILE_PORTABLE|UNIT_FILE_FORCE,
};