mirror of
https://github.com/systemd/systemd.git
synced 2026-11-06 05:17:24 +00:00
sysupdate: apply user xattrs listed in UAPI.16 manifests to installed instances
UAPI.16 file objects may carry an "extendedAttributes" field. When installing a file or directory from a source with a UAPI.16 manifest, let's apply the extended attributes in the "user" namespace listed there to the inode we create, so that they are retained on the target. This is done on a best-effort basis: if the file system does not support extended attributes, or setting them fails for other reasons, this is logged but not fatal, the instance is fully usable without them.
This commit is contained in:
1 parent
e9385e2508
commit
33acdda954
6 files changed
+74
No files matched your search
@@ -758,6 +758,12 @@
|
||||
resources, as well as inline data that is encoded, must consist of the file and nothing else, other
|
||||
such sources are ignored.</para>
|
||||
|
||||
<para>The extended attributes in the <literal>user</literal> namespace listed in the
|
||||
<literal>extendedAttributes</literal> field of a file object of a UAPI.16 manifest are applied to the
|
||||
file or directory created when installing it. This is done on a best-effort basis: if the file system
|
||||
does not support extended attributes, or they cannot be set for other reasons, the instance is
|
||||
installed without them.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v263"/></listitem>
|
||||
</varlistentry>
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ typedef struct Tpm2Handle Tpm2Handle;
|
||||
typedef struct Tpm2PCRValue Tpm2PCRValue;
|
||||
typedef struct Uapi16Contents Uapi16Contents;
|
||||
typedef struct Uapi16Object Uapi16Object;
|
||||
typedef struct Uapi16Xattr Uapi16Xattr;
|
||||
typedef struct UnitInfo UnitInfo;
|
||||
typedef struct UnitResult UnitResult;
|
||||
typedef struct UserRecord UserRecord;
|
||||
|
||||
@@ -63,5 +63,7 @@ Instance *instance_free(Instance *i) {
|
||||
uapi16_contents_done(s);
|
||||
free(i->sources);
|
||||
|
||||
uapi16_xattr_array_free(i->user_xattrs, i->n_user_xattrs);
|
||||
|
||||
return mfree(i);
|
||||
}
|
||||
@@ -53,6 +53,11 @@ struct Instance {
|
||||
Uapi16Contents *sources;
|
||||
size_t n_sources;
|
||||
|
||||
/* The "user" extended attributes listed in the manifest (for web backed sources), which we apply
|
||||
* to the inode we create when installing the instance */
|
||||
Uapi16Xattr *user_xattrs;
|
||||
size_t n_user_xattrs;
|
||||
|
||||
/* The current state of this instance */
|
||||
bool is_partial;
|
||||
bool is_pending;
|
||||
|
||||
@@ -899,6 +899,11 @@ static int uapi16_process_object(Uapi16Object *object, size_t index, void *userd
|
||||
instance->n_sources = object->n_contents;
|
||||
object->n_contents = 0;
|
||||
|
||||
/* Similar, for the extended attributes to apply when installing */
|
||||
instance->user_xattrs = TAKE_PTR(object->user_xattrs);
|
||||
instance->n_user_xattrs = object->n_user_xattrs;
|
||||
object->n_user_xattrs = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
#include "sysupdate-transfer.h"
|
||||
#include "time-util.h"
|
||||
#include "web-util.h"
|
||||
#include "xattr-util.h"
|
||||
|
||||
/* Default value for InstancesMax= for fs object targets */
|
||||
#define DEFAULT_FILE_INSTANCES_MAX 3
|
||||
@@ -1835,6 +1836,54 @@ static int transfer_acquire_source(
|
||||
t, i, cb, userdata);
|
||||
}
|
||||
|
||||
static int instance_apply_user_xattrs(Instance *i, const char *path) {
|
||||
int r;
|
||||
|
||||
assert(i);
|
||||
assert(path);
|
||||
|
||||
/* Applies the user extended attributes listed in the manifest to the installed inode, so that they
|
||||
* are retained on the target. Failing to do so is not fatal, the instance is fully usable without
|
||||
* them. Returns > 0 if any attribute was applied. */
|
||||
|
||||
if (i->n_user_xattrs == 0)
|
||||
return 0;
|
||||
|
||||
_cleanup_close_ int fd = xopenat(AT_FDCWD, path, O_PATH|O_NOFOLLOW);
|
||||
if (fd < 0) {
|
||||
log_warning_errno(fd, "Failed to open '%s' to apply extended attributes, ignoring: %m", path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool applied = false;
|
||||
FOREACH_ARRAY(x, i->user_xattrs, i->n_user_xattrs) {
|
||||
_cleanup_free_ char *n = strjoin("user.", x->name);
|
||||
if (!n)
|
||||
return log_oom();
|
||||
|
||||
r = xsetxattr_full(
|
||||
fd,
|
||||
/* path= */ NULL,
|
||||
AT_EMPTY_PATH,
|
||||
n,
|
||||
x->value.iov_base,
|
||||
x->value.iov_len,
|
||||
/* xattr_flags= */ 0);
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) {
|
||||
log_notice_errno(r, "File system backing '%s' does not support extended attributes, not applying them: %m", path);
|
||||
break;
|
||||
}
|
||||
if (r < 0) {
|
||||
log_warning_errno(r, "Failed to set extended attribute '%s' on '%s', ignoring: %m", n, path);
|
||||
continue;
|
||||
}
|
||||
|
||||
applied = true;
|
||||
}
|
||||
|
||||
return applied;
|
||||
}
|
||||
|
||||
int transfer_acquire_instance(Transfer *t, Instance *i, InstanceMetadata *f, TransferProgress cb, void *userdata) {
|
||||
char offset[DECIMAL_STR_MAX(uint64_t)+1], max_size[DECIMAL_STR_MAX(uint64_t)+1];
|
||||
const char *where = NULL;
|
||||
@@ -2074,6 +2123,12 @@ int transfer_acquire_instance(Transfer *t, Instance *i, InstanceMetadata *f, Tra
|
||||
need_sync = true;
|
||||
}
|
||||
|
||||
r = instance_apply_user_xattrs(i, t->temporary_partial_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0)
|
||||
need_sync = true;
|
||||
|
||||
/* Synchronize */
|
||||
if (t->context->sync && need_sync) {
|
||||
if (t->target.type == RESOURCE_REGULAR_FILE)
|
||||
|
||||
Reference in new issue
Block a user