dissect: try to find partition again on timeout

Not sure, but at the time the target partition device is created or
enumerated, some sysattrs or properties may not be ready.

So, let's find partition on timeout. The device may be ready at that
time.
This commit is contained in:
Yu Watanabe
2021-06-09 02:54:29 +09:00
parent 7f7a50dd15
commit 05c3c620f7
+30 -1
View File
@@ -285,6 +285,8 @@ struct wait_data {
blkid_partition blkidp;
sd_device *found;
uint64_t uevent_seqnum_not_before;
usec_t timestamp_not_before;
DissectImageFlags flags;
};
static inline void wait_data_done(struct wait_data *d) {
@@ -329,6 +331,27 @@ finish:
return sd_event_exit(sd_device_monitor_get_event(monitor), r);
}
static int timeout_handler(sd_event_source *s, uint64_t usec, void *userdata) {
struct wait_data *w = userdata;
int r;
assert(w);
/* Why partition not appeared within the timeout? We may lost some uevent, as some properties
* were not ready when we received uevent... Not sure, but anyway, let's try to find the
* partition again before give up. */
r = find_partition(w->parent_device, w->blkidp, w->timestamp_not_before, w->flags, &w->found);
if (r == -ENXIO)
return log_debug_errno(SYNTHETIC_ERRNO(ETIMEDOUT),
"Partition still not appeared after timeout reached.");
if (r < 0)
return log_debug_errno(r, "Failed to find partition: %m");
log_debug("Partition appeared after timeout reached.");
return sd_event_exit(sd_event_source_get_event(s), 0);
}
static int wait_for_partition_device(
sd_device *parent,
blkid_partition pp,
@@ -379,6 +402,8 @@ static int wait_for_partition_device(
.parent_device = parent,
.blkidp = pp,
.uevent_seqnum_not_before = uevent_seqnum_not_before,
.timestamp_not_before = timestamp_not_before,
.flags = flags,
};
r = sd_device_monitor_start(monitor, device_monitor_handler, &w);
@@ -394,7 +419,11 @@ static int wait_for_partition_device(
r = sd_event_add_time(
event, &timeout_source,
CLOCK_MONOTONIC, deadline, 0,
NULL, INT_TO_PTR(-ETIMEDOUT));
timeout_handler, &w);
if (r < 0)
return r;
r = sd_event_source_set_exit_on_failure(timeout_source, true);
if (r < 0)
return r;
}