Merge pull request #24720 from yuwata/dissect-image-take-reference
dissect-image: make DissectedImage object take reference to DecryptedImage and LoopDevice
This commit is contained in:
+69
-13
@@ -1130,9 +1130,18 @@ DissectedImage* dissected_image_unref(DissectedImage *m) {
|
||||
if (!m)
|
||||
return NULL;
|
||||
|
||||
/* First, clear dissected partitions. */
|
||||
for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++)
|
||||
dissected_partition_done(m->partitions + i);
|
||||
|
||||
/* Second, free decrypted images. This must be after dissected_partition_done(), as freeing
|
||||
* DecryptedImage may try to deactivate partitions. */
|
||||
decrypted_image_unref(m->decrypted_image);
|
||||
|
||||
/* Third, unref LoopDevice. This must be called after the above two, as freeing LoopDevice may try to
|
||||
* remove existing partitions on the loopback block device. */
|
||||
loop_device_unref(m->loop);
|
||||
|
||||
free(m->image_name);
|
||||
free(m->hostname);
|
||||
strv_free(m->machine_info);
|
||||
@@ -1562,19 +1571,22 @@ int dissected_image_mount_and_warn(
|
||||
}
|
||||
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
typedef struct DecryptedPartition {
|
||||
struct DecryptedPartition {
|
||||
struct crypt_device *device;
|
||||
char *name;
|
||||
bool relinquished;
|
||||
} DecryptedPartition;
|
||||
|
||||
struct DecryptedImage {
|
||||
DecryptedPartition *decrypted;
|
||||
size_t n_decrypted;
|
||||
};
|
||||
#endif
|
||||
|
||||
DecryptedImage* decrypted_image_unref(DecryptedImage* d) {
|
||||
typedef struct DecryptedPartition DecryptedPartition;
|
||||
|
||||
struct DecryptedImage {
|
||||
unsigned n_ref;
|
||||
DecryptedPartition *decrypted;
|
||||
size_t n_decrypted;
|
||||
};
|
||||
|
||||
static DecryptedImage* decrypted_image_free(DecryptedImage *d) {
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
int r;
|
||||
|
||||
@@ -1602,7 +1614,25 @@ DecryptedImage* decrypted_image_unref(DecryptedImage* d) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(DecryptedImage, decrypted_image, decrypted_image_free);
|
||||
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
static int decrypted_image_new(DecryptedImage **ret) {
|
||||
_cleanup_(decrypted_image_unrefp) DecryptedImage *d = NULL;
|
||||
|
||||
assert(ret);
|
||||
|
||||
d = new(DecryptedImage, 1);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
|
||||
*d = (DecryptedImage) {
|
||||
.n_ref = 1,
|
||||
};
|
||||
|
||||
*ret = TAKE_PTR(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int make_dm_name_and_node(const void *original_node, const char *suffix, char **ret_name, char **ret_node) {
|
||||
_cleanup_free_ char *name = NULL, *node = NULL;
|
||||
@@ -2102,14 +2132,15 @@ int dissected_image_decrypt(
|
||||
return -EINVAL;
|
||||
|
||||
if (!m->encrypted && !m->verity_ready) {
|
||||
*ret = NULL;
|
||||
if (ret)
|
||||
*ret = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HAVE_LIBCRYPTSETUP
|
||||
d = new0(DecryptedImage, 1);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
r = decrypted_image_new(&d);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
for (PartitionDesignator i = 0; i < _PARTITION_DESIGNATOR_MAX; i++) {
|
||||
DissectedPartition *p = m->partitions + i;
|
||||
@@ -2136,7 +2167,9 @@ int dissected_image_decrypt(
|
||||
}
|
||||
}
|
||||
|
||||
*ret = TAKE_PTR(d);
|
||||
m->decrypted_image = TAKE_PTR(d);
|
||||
if (ret)
|
||||
*ret = decrypted_image_ref(m->decrypted_image);
|
||||
|
||||
return 1;
|
||||
#else
|
||||
@@ -2792,8 +2825,31 @@ finish:
|
||||
return r;
|
||||
}
|
||||
|
||||
int dissect_loop_device(
|
||||
LoopDevice *loop,
|
||||
const VeritySettings *verity,
|
||||
const MountOptions *mount_options,
|
||||
DissectImageFlags flags,
|
||||
DissectedImage **ret) {
|
||||
|
||||
_cleanup_(dissected_image_unrefp) DissectedImage *m = NULL;
|
||||
int r;
|
||||
|
||||
assert(loop);
|
||||
assert(ret);
|
||||
|
||||
r = dissect_image(loop->fd, loop->node, loop->backing_file ?: loop->node, verity, mount_options, flags, &m);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
m->loop = loop_device_ref(loop);
|
||||
|
||||
*ret = TAKE_PTR(m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dissect_loop_device_and_warn(
|
||||
const LoopDevice *loop,
|
||||
LoopDevice *loop,
|
||||
const VeritySettings *verity,
|
||||
const MountOptions *mount_options,
|
||||
DissectImageFlags flags,
|
||||
|
||||
@@ -216,7 +216,9 @@ struct DissectedImage {
|
||||
bool verity_sig_ready:1; /* verity signature logic, fully specified and usable */
|
||||
bool single_file_system:1; /* MBR/GPT or single file system */
|
||||
|
||||
LoopDevice *loop;
|
||||
DissectedPartition partitions[_PARTITION_DESIGNATOR_MAX];
|
||||
DecryptedImage *decrypted_image;
|
||||
|
||||
/* Meta information extracted from /etc/os-release and similar */
|
||||
char *image_name;
|
||||
@@ -267,11 +269,8 @@ int dissect_image(
|
||||
const MountOptions *mount_options,
|
||||
DissectImageFlags flags,
|
||||
DissectedImage **ret);
|
||||
static inline int dissect_loop_device(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret) {
|
||||
assert(loop);
|
||||
return dissect_image(loop->fd, loop->node, loop->backing_file ?: loop->node, verity, mount_options, flags, ret);
|
||||
}
|
||||
int dissect_loop_device_and_warn(const LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret);
|
||||
int dissect_loop_device(LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret);
|
||||
int dissect_loop_device_and_warn(LoopDevice *loop, const VeritySettings *verity, const MountOptions *mount_options, DissectImageFlags flags, DissectedImage **ret);
|
||||
|
||||
DissectedImage* dissected_image_unref(DissectedImage *m);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref);
|
||||
@@ -283,6 +282,7 @@ int dissected_image_mount_and_warn(DissectedImage *m, const char *where, uid_t u
|
||||
|
||||
int dissected_image_acquire_metadata(DissectedImage *m, DissectImageFlags extra_flags);
|
||||
|
||||
DecryptedImage* decrypted_image_ref(DecryptedImage *p);
|
||||
DecryptedImage* decrypted_image_unref(DecryptedImage *p);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(DecryptedImage*, decrypted_image_unref);
|
||||
int decrypted_image_relinquish(DecryptedImage *d);
|
||||
|
||||
@@ -369,6 +369,7 @@ static int loop_configure(
|
||||
return -ENOMEM;
|
||||
|
||||
*d = (LoopDevice) {
|
||||
.n_ref = 1,
|
||||
.fd = TAKE_FD(loop_with_fd),
|
||||
.lock_fd = TAKE_FD(lock_fd),
|
||||
.node = TAKE_PTR(node),
|
||||
@@ -624,7 +625,7 @@ int loop_device_make_by_path(
|
||||
return loop_device_make_internal(path, fd, open_flags, 0, 0, loop_flags, lock_op, ret);
|
||||
}
|
||||
|
||||
LoopDevice* loop_device_unref(LoopDevice *d) {
|
||||
static LoopDevice* loop_device_free(LoopDevice *d) {
|
||||
_cleanup_close_ int control = -1;
|
||||
int r;
|
||||
|
||||
@@ -696,6 +697,8 @@ LoopDevice* loop_device_unref(LoopDevice *d) {
|
||||
return mfree(d);
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(LoopDevice, loop_device, loop_device_free);
|
||||
|
||||
void loop_device_relinquish(LoopDevice *d) {
|
||||
assert(d);
|
||||
|
||||
@@ -796,6 +799,7 @@ int loop_device_open_full(
|
||||
return -ENOMEM;
|
||||
|
||||
*d = (LoopDevice) {
|
||||
.n_ref = 1,
|
||||
.fd = TAKE_FD(fd),
|
||||
.lock_fd = TAKE_FD(lock_fd),
|
||||
.nr = nr,
|
||||
|
||||
@@ -11,6 +11,7 @@ typedef struct LoopDevice LoopDevice;
|
||||
/* Some helpers for setting up loopback block devices */
|
||||
|
||||
struct LoopDevice {
|
||||
unsigned n_ref;
|
||||
int fd;
|
||||
int lock_fd;
|
||||
int nr; /* The loopback device index (i.e. 4 for /dev/loop4); if this object encapsulates a non-loopback block device, set to -1 */
|
||||
@@ -34,6 +35,7 @@ static inline int loop_device_open(const char *loop_path, int open_flags, int lo
|
||||
return loop_device_open_full(loop_path, -1, open_flags, lock_op, ret);
|
||||
}
|
||||
|
||||
LoopDevice* loop_device_ref(LoopDevice *d);
|
||||
LoopDevice* loop_device_unref(LoopDevice *d);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(LoopDevice*, loop_device_unref);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user