sd_device *parent_device;
blkid_partition blkidp;
sd_device *found;
+ uint64_t diskseq;
uint64_t uevent_seqnum_not_before;
usec_t timestamp_not_before;
DissectImageFlags flags;
if (device_for_action(device, SD_DEVICE_REMOVE))
return 0;
- if (w->uevent_seqnum_not_before != UINT64_MAX) {
+ if (w->diskseq != 0) {
+ uint64_t diskseq;
+
+ /* If w->diskseq is non-zero, then we must have a disk seqnum */
+ r = sd_device_get_diskseq(device, &diskseq);
+ if (r < 0) {
+ log_debug_errno(r, "Dropping event because it has no diskseq, but waiting for %" PRIu64, w->diskseq);
+ return 0;
+ }
+ if (diskseq < w->diskseq) {
+ log_debug("Dropping event because diskseq too old (%" PRIu64 " < %" PRIu64 ")",
+ diskseq, w->diskseq);
+ return 0;
+ }
+ if (diskseq > w->diskseq) {
+ r = -EBUSY;
+ goto finish; /* Newer than what we were expecting, so we missed it, stop waiting */
+ }
+ } else if (w->uevent_seqnum_not_before != UINT64_MAX) {
uint64_t seqnum;
r = sd_device_get_seqnum(device, &seqnum);
sd_device *parent,
blkid_partition pp,
usec_t deadline,
+ uint64_t diskseq,
uint64_t uevent_seqnum_not_before,
usec_t timestamp_not_before,
DissectImageFlags flags,
_cleanup_(wait_data_done) struct wait_data w = {
.parent_device = parent,
.blkidp = pp,
+ .diskseq = diskseq,
.uevent_seqnum_not_before = uevent_seqnum_not_before,
.timestamp_not_before = timestamp_not_before,
.flags = flags,
return r;
}
- r = sd_event_add_time_relative(
- event, &retry_source,
- CLOCK_MONOTONIC, 500 * USEC_PER_MSEC, 0,
- retry_handler, &w);
- if (r < 0)
- return r;
+ /* If we don't have a disk sequence number then we cannot do exact matching,
+ * and we cannot know if we missed it or if it has not been sent yet, so set
+ * up additional retries to increase the chances of receiving the event. */
+ if (diskseq == 0) {
+ r = sd_event_add_time_relative(
+ event, &retry_source,
+ CLOCK_MONOTONIC, 500 * USEC_PER_MSEC, 0,
+ retry_handler, &w);
+ if (r < 0)
+ return r;
- r = sd_event_source_set_exit_on_failure(retry_source, true);
- if (r < 0)
- return r;
+ r = sd_event_source_set_exit_on_failure(retry_source, true);
+ if (r < 0)
+ return r;
+ }
r = sd_event_loop(event);
if (r < 0)
int fd,
const VeritySettings *verity,
const MountOptions *mount_options,
+ uint64_t diskseq,
uint64_t uevent_seqnum_not_before,
usec_t timestamp_not_before,
DissectImageFlags flags,
if (!pp)
return errno_or_else(EIO);
- r = wait_for_partition_device(d, pp, deadline, uevent_seqnum_not_before, timestamp_not_before, flags, &q);
+ r = wait_for_partition_device(d, pp, deadline, diskseq, uevent_seqnum_not_before, timestamp_not_before, flags, &q);
if (r < 0)
return r;
const char *name,
const VeritySettings *verity,
const MountOptions *mount_options,
+ uint64_t diskseq,
uint64_t uevent_seqnum_not_before,
usec_t timestamp_not_before,
DissectImageFlags flags,
name = buffer;
}
- r = dissect_image(fd, verity, mount_options, uevent_seqnum_not_before, timestamp_not_before, flags, ret);
+ r = dissect_image(fd, verity, mount_options, diskseq, uevent_seqnum_not_before, timestamp_not_before, flags, ret);
switch (r) {
case -EOPNOTSUPP:
if (r < 0)
return log_error_errno(r, "Failed to set up loopback device for %s: %m", image);
- r = dissect_image_and_warn(d->fd, image, &verity, NULL, d->uevent_seqnum_not_before, d->timestamp_not_before, flags, &dissected_image);
+ r = dissect_image_and_warn(d->fd, image, &verity, NULL, d->diskseq, d->uevent_seqnum_not_before, d->timestamp_not_before, flags, &dissected_image);
if (r < 0)
return r;
loop_device->fd,
&verity,
options,
+ loop_device->diskseq,
loop_device->uevent_seqnum_not_before,
loop_device->timestamp_not_before,
dissect_image_flags,
loop_device->fd,
&verity,
options,
+ loop_device->diskseq,
loop_device->uevent_seqnum_not_before,
loop_device->timestamp_not_before,
dissect_image_flags | DISSECT_IMAGE_NO_PARTITION_TABLE,
const char* mount_options_from_designator(const MountOptions *options, PartitionDesignator designator);
int probe_filesystem(const char *node, char **ret_fstype);
-int dissect_image(int fd, const VeritySettings *verity, const MountOptions *mount_options, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
-int dissect_image_and_warn(int fd, const char *name, const VeritySettings *verity, const MountOptions *mount_options, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
+int dissect_image(int fd, const VeritySettings *verity, const MountOptions *mount_options, uint64_t diskseq, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
+int dissect_image_and_warn(int fd, const char *name, const VeritySettings *verity, const MountOptions *mount_options, uint64_t diskseq, uint64_t uevent_seqnum_not_before, usec_t timestamp_not_before, DissectImageFlags flags, DissectedImage **ret);
DissectedImage* dissected_image_unref(DissectedImage *m);
DEFINE_TRIVIAL_CLEANUP_FUNC(DissectedImage*, dissected_image_unref);
log_notice("Acquired loop device %s, will mount on %s", loop->node, mounted);
- r = dissect_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, loop->timestamp_not_before, DISSECT_IMAGE_READ_ONLY, &dissected);
+ r = dissect_image(loop->fd, NULL, NULL, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, DISSECT_IMAGE_READ_ONLY, &dissected);
if (r < 0)
log_error_errno(r, "Failed dissect loopback device %s: %m", loop->node);
assert_se(r >= 0);
sfdisk = NULL;
assert_se(loop_device_make(fd, O_RDWR, 0, UINT64_MAX, LO_FLAGS_PARTSCAN, &loop) >= 0);
- assert_se(dissect_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
+ assert_se(dissect_image(loop->fd, NULL, NULL, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
assert_se(dissected->partitions[PARTITION_ESP].found);
assert_se(dissected->partitions[PARTITION_ESP].node);
assert_se(make_filesystem(dissected->partitions[PARTITION_HOME].node, "ext4", "home", id, true) >= 0);
dissected = dissected_image_unref(dissected);
- assert_se(dissect_image(loop->fd, NULL, NULL, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
+ assert_se(dissect_image(loop->fd, NULL, NULL, loop->diskseq, loop->uevent_seqnum_not_before, loop->timestamp_not_before, 0, &dissected) >= 0);
assert_se(mkdtemp_malloc(NULL, &mounted) >= 0);