X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?p=elogind.git;a=blobdiff_plain;f=src%2Fmanager.c;h=d690a0f16bca0dbfd091ff7f1294dd6a526fae8b;hp=f2ec2b72ada50e6608b84f25419bd46c90e58211;hb=e9ddabc246ced239cbce436e16792dc4c3d1b52d;hpb=0003d1ab75f82dd6aa143582c5bd815b3b8f65e8 diff --git a/src/manager.c b/src/manager.c index f2ec2b72a..d690a0f16 100644 --- a/src/manager.c +++ b/src/manager.c @@ -216,7 +216,7 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) { m->audit_fd = -1; #endif - m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = -1; + m->signal_watch.fd = m->mount_watch.fd = m->udev_watch.fd = m->epoll_fd = m->dev_autofs_fd = m->swap_watch.fd = -1; m->current_job_id = 1; /* start as id #1, so that we can leave #0 around as "null-like" value */ if (!(m->environment = strv_copy(environ))) @@ -1133,7 +1133,8 @@ static void transaction_minimize_impact(Manager *m) { j->type == JOB_STOP && UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(j->unit)); changes_existing_job = - j->unit->meta.job && job_type_is_conflicting(j->type, j->unit->meta.job->type); + j->unit->meta.job && + job_type_is_conflicting(j->type, j->unit->meta.job->type); if (!stops_running_service && !changes_existing_job) continue; @@ -1198,6 +1199,8 @@ static int transaction_apply(Manager *m) { job_add_to_run_queue(j); job_add_to_dbus_queue(j); job_start_timer(j); + + log_debug("Installed new job %s/%s as %u", j->unit->meta.id, job_type_to_string(j->type), (unsigned) j->id); } /* As last step, kill all remaining job dependencies. */ @@ -1232,7 +1235,7 @@ static int transaction_activate(Manager *m, JobMode mode, DBusError *e) { /* Second step: Try not to stop any running services if * we don't have to. Don't try to reverse running * jobs if we don't have to. */ - if (mode != JOB_ISOLATE) + if (mode == JOB_FAIL) transaction_minimize_impact(m); /* Third step: Drop redundant jobs */ @@ -1413,7 +1416,7 @@ static int transaction_add_job_and_dependencies( if (type != JOB_STOP && unit->meta.load_state == UNIT_ERROR) { dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load: %s. " - "You might find more information in the system logs.", + "See system logs and 'systemctl status' for details.", unit->meta.id, strerror(-unit->meta.load_error)); return -EINVAL; @@ -1444,6 +1447,10 @@ static int transaction_add_job_and_dependencies( if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR) goto fail; + SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BIND_TO], i) + if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR) + goto fail; + SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i) if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override, false, e, NULL)) < 0 && r != -EBADR) { log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, bus_error(e, r)); @@ -1477,7 +1484,7 @@ static int transaction_add_job_and_dependencies( goto fail; SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTED_BY], i) - if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR) + if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, false, override, false, e, NULL)) < 0 && r != -EBADR) goto fail; } else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) { @@ -1485,6 +1492,10 @@ static int transaction_add_job_and_dependencies( SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i) if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR) goto fail; + + SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_BOUND_BY], i) + if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, false, e, NULL)) < 0 && r != -EBADR) + goto fail; } /* JOB_VERIFY_STARTED, JOB_RELOAD require no dependency handling */ @@ -1517,7 +1528,7 @@ static int transaction_add_isolate_jobs(Manager *m) { continue; /* No need to stop inactive jobs */ - if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u))) + if (UNIT_IS_INACTIVE_OR_FAILED(unit_active_state(u)) && !u->meta.job) continue; /* Is there already something listed for this? */ @@ -2171,6 +2182,11 @@ static int process_event(Manager *m, struct epoll_event *ev) { mount_fd_event(m, ev->events); break; + case WATCH_SWAP: + /* Some swap table change, intended for the swap subsystem */ + swap_fd_event(m, ev->events); + break; + case WATCH_UDEV: /* Some notification from udev, intended for the device subsystem */ device_fd_event(m, ev->events); @@ -2485,9 +2501,11 @@ int manager_serialize(Manager *m, FILE *f, FDSet *fds) { assert(f); assert(fds); - fprintf(f, "startup-timestamp=%llu %llu\n\n", - (unsigned long long) m->startup_timestamp.realtime, - (unsigned long long) m->startup_timestamp.monotonic); + dual_timestamp_serialize(f, "initrd-timestamp", &m->initrd_timestamp); + dual_timestamp_serialize(f, "startup-timestamp", &m->startup_timestamp); + dual_timestamp_serialize(f, "finish-timestamp", &m->finish_timestamp); + + fputc('\n', f); HASHMAP_FOREACH_KEY(u, t, m->units, i) { if (u->meta.id != t) @@ -2538,16 +2556,13 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds) { if (l[0] == 0) break; - if (startswith(l, "startup-timestamp=")) { - unsigned long long a, b; - - if (sscanf(l+18, "%lli %llu", &a, &b) != 2) - log_debug("Failed to parse startup timestamp value %s", l+18); - else { - m->startup_timestamp.realtime = a; - m->startup_timestamp.monotonic = b; - } - } else + if (startswith(l, "initrd-timestamp=")) + dual_timestamp_deserialize(l+17, &m->initrd_timestamp); + else if (startswith(l, "startup-timestamp=")) + dual_timestamp_deserialize(l+18, &m->startup_timestamp); + else if (startswith(l, "finish-timestamp=")) + dual_timestamp_deserialize(l+17, &m->finish_timestamp); + else log_debug("Unknown serialization item '%s'", l); } @@ -2703,7 +2718,7 @@ bool manager_unit_pending_inactive(Manager *m, const char *name) { } void manager_check_finished(Manager *m) { - char userspace[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX]; + char userspace[FORMAT_TIMESPAN_MAX], initrd[FORMAT_TIMESPAN_MAX], kernel[FORMAT_TIMESPAN_MAX], sum[FORMAT_TIMESPAN_MAX]; assert(m); @@ -2715,15 +2730,26 @@ void manager_check_finished(Manager *m) { dual_timestamp_get(&m->finish_timestamp); - if (m->running_as == MANAGER_SYSTEM) - log_info("Startup finished in %s (kernel) + %s (userspace) = %s.", - format_timespan(kernel, sizeof(kernel), - m->startup_timestamp.monotonic), - format_timespan(userspace, sizeof(userspace), - m->finish_timestamp.monotonic - m->startup_timestamp.monotonic), - format_timespan(sum, sizeof(sum), - m->finish_timestamp.monotonic)); - else + if (m->running_as == MANAGER_SYSTEM) { + if (dual_timestamp_is_set(&m->initrd_timestamp)) { + log_info("Startup finished in %s (kernel) + %s (initrd) + %s (userspace) = %s.", + format_timespan(kernel, sizeof(kernel), + m->initrd_timestamp.monotonic), + format_timespan(initrd, sizeof(initrd), + m->startup_timestamp.monotonic - m->initrd_timestamp.monotonic), + format_timespan(userspace, sizeof(userspace), + m->finish_timestamp.monotonic - m->startup_timestamp.monotonic), + format_timespan(sum, sizeof(sum), + m->finish_timestamp.monotonic)); + } else + log_info("Startup finished in %s (kernel) + %s (userspace) = %s.", + format_timespan(kernel, sizeof(kernel), + m->startup_timestamp.monotonic), + format_timespan(userspace, sizeof(userspace), + m->finish_timestamp.monotonic - m->startup_timestamp.monotonic), + format_timespan(sum, sizeof(sum), + m->finish_timestamp.monotonic)); + } else log_debug("Startup finished in %s.", format_timespan(userspace, sizeof(userspace), m->finish_timestamp.monotonic - m->startup_timestamp.monotonic));