Commit e6d1bc24 authored by Alexander Achenbach's avatar Alexander Achenbach Committed by Steve Langasek
Browse files

Don't block other, unrelated mounts from being processed while one

mount is blocked on its mounting signal to process.
parent 1d77e7ee
mountall (2.41) UNRELEASED; urgency=low
[ Alexander Achenbach ]
* Don't block other, unrelated mounts from being processed while one
mount is blocked on its mounting signal to process. LP: #643289.
-- Steve Langasek <vorlon@debian.org> Sat, 08 Sep 2012 00:10:09 -0700
mountall (2.40) unstable; urgency=low
* Add /run/user as a default mountpoint, in support of $XDG_RUNTIME_DIR.
......
......@@ -126,6 +126,8 @@ struct mount {
int fsck_fix;
int ready;
DBusPendingCall * pending_call;
Error error;
char * type;
......@@ -185,6 +187,7 @@ void trigger_events (void);
void try_mounts (void);
void try_mount (Mount *mnt, int force);
void mounting_event_handled(void *data, NihDBusMessage *message);
int find_on_path (const char *name);
int find_fsck (const char *type);
......@@ -209,7 +212,8 @@ void write_mtab (void);
void mount_showthrough (Mount *root);
void upstart_disconnected (DBusConnection *connection);
void emit_event (const char *name, Mount *mnt);
void emit_event (const char *name, Mount *mnt,
void (*cb) (void *, NihDBusMessage *message));
void emit_event_error (void *data, NihDBusMessage *message);
void udev_monitor_watcher (struct udev_monitor *udev_monitor,
......@@ -479,6 +483,8 @@ new_mount (const char *mountpoint,
mnt->fsck_fix = FALSE;
mnt->ready = FALSE;
mnt->pending_call = NULL;
mnt->error = ERROR_NONE;
mnt->type = NULL;
......@@ -871,6 +877,9 @@ parse_mountinfo_file (int reparsed)
mnt = find_mount (mountpoint);
if (mnt
&& strcmp (type, "swap")) {
int needed_remount = needs_remount (mnt);
if (! strcmp (type, "rootfs"))
type = NULL;
......@@ -883,6 +892,11 @@ parse_mountinfo_file (int reparsed)
if (mnt->mount_opts)
nih_unref (mnt->mount_opts, mounts);
mnt->mount_opts = opts;
/* If remounted, treat as newly done mount below. */
if (needed_remount && !needs_remount (mnt))
mnt->mounted = FALSE;
} else {
mnt = new_mount (mountpoint, device, FALSE, type, opts);
mnt->mount_opts = opts;
......@@ -891,7 +905,14 @@ parse_mountinfo_file (int reparsed)
if (sscanf (dev, "%d:%d", &maj, &min) == 2)
mnt->mounted_dev = makedev (maj, min);
if (reparsed && (! mnt->mounted)) {
if (mnt->mounted)
continue;
/* Fully update mounted state if reparsed.
* If invoked first time, just set the flag and leave complete
* state update (including event trigger) to mark_mounted ().
*/
if (reparsed) {
mounted (mnt);
} else {
mnt->mounted = TRUE;
......@@ -1489,7 +1510,7 @@ mounted (Mount *mnt)
}
}
emit_event ("mounted", mnt);
emit_event ("mounted", mnt, NULL);
/* Any previous mount options no longer apply
* (ie. we're not read-only anymore)
......@@ -1610,7 +1631,7 @@ trigger_events (void)
if ((! virtual_triggered)
&& (num_virtual_mounted == num_virtual)) {
nih_info (_("%s finished"), "virtual");
emit_event ("virtual-filesystems", NULL);
emit_event ("virtual-filesystems", NULL, NULL);
virtual_triggered = TRUE;
}
......@@ -1619,7 +1640,7 @@ trigger_events (void)
&& virtual_triggered
&& (num_local_mounted == num_local)) {
nih_info (_("%s finished"), "local");
emit_event ("local-filesystems", NULL);
emit_event ("local-filesystems", NULL, NULL);
local_triggered = TRUE;
}
......@@ -1628,7 +1649,7 @@ trigger_events (void)
&& virtual_triggered
&& (num_remote_mounted == num_remote)) {
nih_info (_("%s finished"), "remote");
emit_event ("remote-filesystems", NULL);
emit_event ("remote-filesystems", NULL, NULL);
remote_triggered = TRUE;
}
......@@ -1638,7 +1659,7 @@ trigger_events (void)
&& local_triggered
&& remote_triggered) {
nih_info (_("All filesystems mounted"));
emit_event ("filesystem", NULL);
emit_event ("filesystem", NULL, NULL);
filesystem_triggered = TRUE;
}
......@@ -1646,7 +1667,7 @@ trigger_events (void)
if ((! swap_triggered)
&& (num_swap_mounted == num_swap)) {
nih_info (_("%s finished"), "swap");
emit_event ("all-swaps", NULL);
emit_event ("all-swaps", NULL, NULL);
swap_triggered = TRUE;
}
......@@ -1692,7 +1713,7 @@ is_device_ready (void * data,
|| (! strncmp (mnt->device, "LABEL=", 6))))
{
nih_message ("%s device not ready in ROOTDELAY sec", MOUNT_NAME (mnt));
emit_event ("device-not-ready", mnt);
emit_event ("device-not-ready", mnt, NULL);
}
}
}
......@@ -1760,6 +1781,20 @@ try_mounts (void)
}
if (all) {
/* All mounts have been attempted, so wait for
* pending events.
*/
NIH_LIST_FOREACH (mounts, iter) {
Mount *mnt = (Mount *)iter;
if (!mnt->pending_call)
continue;
dbus_pending_call_block (mnt->pending_call);
dbus_pending_call_unref (mnt->pending_call);
mnt->pending_call = NULL;
}
if (control_server) {
dbus_server_disconnect (control_server);
dbus_server_unref (control_server);
......@@ -1777,6 +1812,9 @@ try_mount (Mount *mnt,
nih_assert (mnt != NULL);
if (mnt->pending_call)
return;
NIH_LIST_FOREACH (&mnt->deps, dep_iter) {
NihListEntry *dep_entry = (NihListEntry *)dep_iter;
Mount * dep = (Mount *)dep_entry->data;
......@@ -1865,17 +1903,33 @@ try_mount (Mount *mnt,
return;
}
/* Queue a filesystem check if not yet ready, otherwise run
* swapon or mount as appropriate.
/* Queue a filesystem check if not yet ready, otherwise emit mounting
* event (callback will run swapon or mount as appropriate).
*/
if ((! mnt->ready)
&& (! is_remote (mnt))) {
run_fsck (mnt);
} else if (! strcmp (mnt->type, "swap")) {
emit_event ("mounting", mnt);
nih_info ("mounting event sent for swap %s", mnt->device);
emit_event ("mounting", mnt, mounting_event_handled);
} else {
nih_info ("mounting event sent for %s", mnt->mountpoint);
emit_event ("mounting", mnt, mounting_event_handled);
}
}
void
mounting_event_handled (void *data,
NihDBusMessage *message)
{
Mount *mnt = (Mount *)data;
if (!strcmp(mnt->type, "swap")) {
nih_info ("mounting event handled for swap %s", mnt->device);
run_swapon (mnt);
} else {
emit_event ("mounting", mnt);
nih_info ("mounting event handled for %s", mnt->mountpoint);
run_mount (mnt, FALSE);
}
}
......@@ -2211,14 +2265,9 @@ run_mount_finished (Mount *mnt,
/* Parse mountinfo to see what mount did; in particular to update
* the type if multiple types are listed in fstab.
* Let parse_mountinfo () invoke mounted () to update state.
*/
if (! mnt->mounted) {
parse_mountinfo ();
if (! mnt->mounted)
mounted (mnt);
} else {
mounted (mnt);
}
parse_mountinfo ();
}
......@@ -2579,11 +2628,13 @@ upstart_disconnected (DBusConnection *connection)
void
emit_event (const char *name,
Mount * mnt)
Mount * mnt,
void (*cb) (void *, NihDBusMessage *message))
{
DBusPendingCall *pending_call;
nih_local char **env = NULL;
size_t env_len = 0;
void *reply_data = NULL;
nih_assert (name != NULL);
......@@ -2622,23 +2673,43 @@ emit_event (const char *name,
nih_discard (var);
}
if (mnt && cb)
reply_data = mnt;
pending_call = NIH_SHOULD (upstart_emit_event (upstart,
name, env, mnt ? TRUE : FALSE,
NULL, emit_event_error, NULL,
name, env, reply_data ? TRUE : FALSE,
reply_data ? cb : NULL,
emit_event_error, reply_data,
NIH_DBUS_TIMEOUT_NEVER));
if (! pending_call) {
if (pending_call) {
if (reply_data) {
/* If previous event is still pending, wait for it. */
if (mnt->pending_call) {
dbus_pending_call_block (mnt->pending_call);
dbus_pending_call_unref (mnt->pending_call);
}
mnt->pending_call = pending_call;
} else {
/* Immediate return from upstart, wait for it. */
dbus_pending_call_block (pending_call);
dbus_pending_call_unref (pending_call);
}
} else {
NihError *err;
err = nih_error_get ();
nih_warn ("%s", err->message);
nih_free (err);
return;
}
dbus_pending_call_block (pending_call);
dbus_pending_call_unref (pending_call);
}
void
......@@ -3727,7 +3798,7 @@ change_mount_device (const char *devname,
else {
nih_free (mnt->device);
mnt->device = newdev;
emit_event ("changed-device", mnt);
emit_event ("changed-device", mnt, NULL);
}
}
break;
......@@ -3952,7 +4023,7 @@ main (int argc,
nih_free (err);
}
if (!ret)
emit_event("mountallServer", NULL);
emit_event("mountallServer", NULL, NULL);
/* Activate the timer for a fs that is local, unmounted and waits for
* a device to be ready, before it can be mounted onto it. Timer on
* only for fs not marked with a "nobootwait=1" */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment