chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
mount: add implicit umount.target conflicts only in system mode
[elogind.git]
/
src
/
manager.c
diff --git
a/src/manager.c
b/src/manager.c
index 554dd8e866b9910be9c80bb876fdd6941e612027..638ef2f4500af4997ea01f946ee2a039706c5a95 100644
(file)
--- a/
src/manager.c
+++ b/
src/manager.c
@@
-32,7
+32,6
@@
#include <sys/reboot.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <sys/reboot.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
-#include <libcgroup.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/types.h>
#include <termios.h>
#include <fcntl.h>
#include <sys/types.h>
@@
-54,6
+53,7
@@
#include "missing.h"
#include "path-lookup.h"
#include "special.h"
#include "missing.h"
#include "path-lookup.h"
#include "special.h"
+#include "bus-errors.h"
/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
#define GC_QUEUE_ENTRIES_MAX 16
/* As soon as 16 units are in our GC queue, make sure to run a gc sweep */
#define GC_QUEUE_ENTRIES_MAX 16
@@
-83,7
+83,7
@@
static int manager_setup_notify(Manager *m) {
zero(sa);
sa.sa.sa_family = AF_UNIX;
zero(sa);
sa.sa.sa_family = AF_UNIX;
- if (
m->running_as == MANAGER_SESSION
)
+ if (
getpid() != 1
)
snprintf(sa.un.sun_path+1, sizeof(sa.un.sun_path)-1, NOTIFY_SOCKET "/%llu", random_ull());
else
strncpy(sa.un.sun_path+1, NOTIFY_SOCKET, sizeof(sa.un.sun_path)-1);
snprintf(sa.un.sun_path+1, sizeof(sa.un.sun_path)-1, NOTIFY_SOCKET "/%llu", random_ull());
else
strncpy(sa.un.sun_path+1, NOTIFY_SOCKET, sizeof(sa.un.sun_path)-1);
@@
-183,7
+183,7
@@
static int manager_setup_signals(Manager *m) {
return 0;
}
return 0;
}
-int manager_new(ManagerRunningAs running_as,
bool confirm_spawn,
Manager **_m) {
+int manager_new(ManagerRunningAs running_as, Manager **_m) {
Manager *m;
int r = -ENOMEM;
char *p;
Manager *m;
int r = -ENOMEM;
char *p;
@@
-195,11
+195,10
@@
int manager_new(ManagerRunningAs running_as, bool confirm_spawn, Manager **_m) {
if (!(m = new0(Manager, 1)))
return -ENOMEM;
if (!(m = new0(Manager, 1)))
return -ENOMEM;
- timestamp_get(&m->startup_timestamp);
+
dual_
timestamp_get(&m->startup_timestamp);
m->running_as = running_as;
m->running_as = running_as;
- m->confirm_spawn = confirm_spawn;
- m->name_data_slot = -1;
+ m->name_data_slot = m->subscribed_data_slot = -1;
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->pin_cgroupfs_fd = -1;
m->exit_code = _MANAGER_EXIT_CODE_INVALID;
m->pin_cgroupfs_fd = -1;
@@
-421,7
+420,8
@@
void manager_free(Manager *m) {
/* If we reexecute ourselves, we keep the root cgroup
* around */
/* If we reexecute ourselves, we keep the root cgroup
* around */
- manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE);
+ if (m->exit_code != MANAGER_REEXECUTE)
+ manager_shutdown_cgroup(m);
bus_done(m);
bus_done(m);
@@
-690,7
+690,7
@@
static int delete_one_unmergeable_job(Manager *m, Job *j) {
return -ENOEXEC;
/* Ok, we can drop one, so let's do so. */
return -ENOEXEC;
/* Ok, we can drop one, so let's do so. */
- log_
debug
("Trying to fix job merging by deleting job %s/%s", d->unit->meta.id, job_type_to_string(d->type));
+ log_
notice
("Trying to fix job merging by deleting job %s/%s", d->unit->meta.id, job_type_to_string(d->type));
transaction_delete_job(m, d, true);
return 0;
}
transaction_delete_job(m, d, true);
return 0;
}
@@
-698,7
+698,7
@@
static int delete_one_unmergeable_job(Manager *m, Job *j) {
return -EINVAL;
}
return -EINVAL;
}
-static int transaction_merge_jobs(Manager *m) {
+static int transaction_merge_jobs(Manager *m
, DBusError *e
) {
Job *j;
Iterator i;
int r;
Job *j;
Iterator i;
int r;
@@
-727,6
+727,8
@@
static int transaction_merge_jobs(Manager *m) {
return -EAGAIN;
/* We couldn't merge anything. Failure */
return -EAGAIN;
/* We couldn't merge anything. Failure */
+ dbus_set_error(e, BUS_ERROR_TRANSACTION_JOBS_CONFLICTING, "Transaction contains conflicting jobs '%s' and '%s' for %s. Probably contradicting requirement dependencies configured.",
+ job_type_to_string(t), job_type_to_string(k->type), k->unit->meta.id);
return r;
}
}
return r;
}
}
@@
-813,7
+815,7
@@
static bool unit_matters_to_anchor(Unit *u, Job *j) {
return false;
}
return false;
}
-static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned generation) {
+static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned generation
, DBusError *e
) {
Iterator i;
Unit *u;
int r;
Iterator i;
Unit *u;
int r;
@@
-841,17
+843,17
@@
static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned
* job to remove. We use the marker to find our way
* back, since smart how we are we stored our way back
* in there. */
* job to remove. We use the marker to find our way
* back, since smart how we are we stored our way back
* in there. */
- log_
debu
g("Found ordering cycle on %s/%s", j->unit->meta.id, job_type_to_string(j->type));
+ log_
warnin
g("Found ordering cycle on %s/%s", j->unit->meta.id, job_type_to_string(j->type));
for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) {
for (k = from; k; k = ((k->generation == generation && k->marker != k) ? k->marker : NULL)) {
- log_
debug
("Walked on cycle path to %s/%s", k->unit->meta.id, job_type_to_string(k->type));
+ log_
info
("Walked on cycle path to %s/%s", k->unit->meta.id, job_type_to_string(k->type));
if (!k->installed &&
!unit_matters_to_anchor(k->unit, k)) {
/* Ok, we can drop this one, so let's
* do so. */
if (!k->installed &&
!unit_matters_to_anchor(k->unit, k)) {
/* Ok, we can drop this one, so let's
* do so. */
- log_
debu
g("Breaking order cycle by deleting job %s/%s", k->unit->meta.id, job_type_to_string(k->type));
+ log_
warnin
g("Breaking order cycle by deleting job %s/%s", k->unit->meta.id, job_type_to_string(k->type));
transaction_delete_unit(m, k->unit);
return -EAGAIN;
}
transaction_delete_unit(m, k->unit);
return -EAGAIN;
}
@@
-862,8
+864,9
@@
static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned
break;
}
break;
}
- log_
debug
("Unable to break cycle");
+ log_
error
("Unable to break cycle");
+ dbus_set_error(e, BUS_ERROR_TRANSACTION_ORDER_IS_CYCLIC, "Transaction order is cyclic. See logs for details.");
return -ENOEXEC;
}
return -ENOEXEC;
}
@@
-888,7
+891,7
@@
static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned
if (!(o = u->meta.job))
continue;
if (!(o = u->meta.job))
continue;
- if ((r = transaction_verify_order_one(m, o, j, generation)) < 0)
+ if ((r = transaction_verify_order_one(m, o, j, generation
, e
)) < 0)
return r;
}
return r;
}
@@
-899,7
+902,7
@@
static int transaction_verify_order_one(Manager *m, Job *j, Job *from, unsigned
return 0;
}
return 0;
}
-static int transaction_verify_order(Manager *m, unsigned *generation) {
+static int transaction_verify_order(Manager *m, unsigned *generation
, DBusError *e
) {
Job *j;
int r;
Iterator i;
Job *j;
int r;
Iterator i;
@@
-914,7
+917,7
@@
static int transaction_verify_order(Manager *m, unsigned *generation) {
g = (*generation)++;
HASHMAP_FOREACH(j, m->transaction_jobs, i)
g = (*generation)++;
HASHMAP_FOREACH(j, m->transaction_jobs, i)
- if ((r = transaction_verify_order_one(m, j, NULL, g)) < 0)
+ if ((r = transaction_verify_order_one(m, j, NULL, g
, e
)) < 0)
return r;
return 0;
return r;
return 0;
@@
-946,7
+949,7
@@
static void transaction_collect_garbage(Manager *m) {
} while (again);
}
} while (again);
}
-static int transaction_is_destructive(Manager *m) {
+static int transaction_is_destructive(Manager *m
, DBusError *e
) {
Iterator i;
Job *j;
Iterator i;
Job *j;
@@
-963,8
+966,11
@@
static int transaction_is_destructive(Manager *m) {
if (j->unit->meta.job &&
j->unit->meta.job != j &&
if (j->unit->meta.job &&
j->unit->meta.job != j &&
- !job_type_is_superset(j->type, j->unit->meta.job->type))
+ !job_type_is_superset(j->type, j->unit->meta.job->type)) {
+
+ dbus_set_error(e, BUS_ERROR_TRANSACTION_IS_DESTRUCTIVE, "Transaction is destructive.");
return -EEXIST;
return -EEXIST;
+ }
}
return 0;
}
return 0;
@@
-1005,13
+1011,13
@@
static void transaction_minimize_impact(Manager *m) {
continue;
if (stops_running_service)
continue;
if (stops_running_service)
- log_
debug
("%s/%s would stop a running service.", j->unit->meta.id, job_type_to_string(j->type));
+ log_
info
("%s/%s would stop a running service.", j->unit->meta.id, job_type_to_string(j->type));
if (changes_existing_job)
if (changes_existing_job)
- log_
debug
("%s/%s would change existing job.", j->unit->meta.id, job_type_to_string(j->type));
+ log_
info
("%s/%s would change existing job.", j->unit->meta.id, job_type_to_string(j->type));
/* Ok, let's get rid of this */
/* Ok, let's get rid of this */
- log_
debug
("Deleting %s/%s to minimize impact.", j->unit->meta.id, job_type_to_string(j->type));
+ log_
info
("Deleting %s/%s to minimize impact.", j->unit->meta.id, job_type_to_string(j->type));
transaction_delete_job(m, j, true);
again = true;
transaction_delete_job(m, j, true);
again = true;
@@
-1081,7
+1087,7
@@
rollback:
return r;
}
return r;
}
-static int transaction_activate(Manager *m, JobMode mode) {
+static int transaction_activate(Manager *m, JobMode mode
, DBusError *e
) {
int r;
unsigned generation = 1;
int r;
unsigned generation = 1;
@@
-1108,11
+1114,11
@@
static int transaction_activate(Manager *m, JobMode mode) {
/* Fifth step: verify order makes sense and correct
* cycles if necessary and possible */
/* Fifth step: verify order makes sense and correct
* cycles if necessary and possible */
- if ((r = transaction_verify_order(m, &generation)) >= 0)
+ if ((r = transaction_verify_order(m, &generation
, e
)) >= 0)
break;
if (r != -EAGAIN) {
break;
if (r != -EAGAIN) {
- log_
debug("Requested transaction contains an unfixable cyclic ordering dependency: %s", strerror(-
r));
+ log_
warning("Requested transaction contains an unfixable cyclic ordering dependency: %s", bus_error(e,
r));
goto rollback;
}
goto rollback;
}
@@
-1124,11
+1130,11
@@
static int transaction_activate(Manager *m, JobMode mode) {
/* Sixth step: let's drop unmergeable entries if
* necessary and possible, merge entries we can
* merge */
/* Sixth step: let's drop unmergeable entries if
* necessary and possible, merge entries we can
* merge */
- if ((r = transaction_merge_jobs(m)) >= 0)
+ if ((r = transaction_merge_jobs(m
, e
)) >= 0)
break;
if (r != -EAGAIN) {
break;
if (r != -EAGAIN) {
- log_
debug("Requested transaction contains unmergable jobs: %s", strerror(-
r));
+ log_
warning("Requested transaction contains unmergable jobs: %s", bus_error(e,
r));
goto rollback;
}
goto rollback;
}
@@
-1145,14
+1151,14
@@
static int transaction_activate(Manager *m, JobMode mode) {
/* Ninth step: check whether we can actually apply this */
if (mode == JOB_FAIL)
/* Ninth step: check whether we can actually apply this */
if (mode == JOB_FAIL)
- if ((r = transaction_is_destructive(m)) < 0) {
- log_
debug("Requested transaction contradicts existing jobs: %s", strerror(-
r));
+ if ((r = transaction_is_destructive(m
, e
)) < 0) {
+ log_
notice("Requested transaction contradicts existing jobs: %s", bus_error(e,
r));
goto rollback;
}
/* Tenth step: apply changes */
if ((r = transaction_apply(m)) < 0) {
goto rollback;
}
/* Tenth step: apply changes */
if ((r = transaction_apply(m)) < 0) {
- log_
debu
g("Failed to apply transaction: %s", strerror(-r));
+ log_
warnin
g("Failed to apply transaction: %s", strerror(-r));
goto rollback;
}
goto rollback;
}
@@
-1239,7
+1245,7
@@
void manager_transaction_unlink_job(Manager *m, Job *j, bool delete_dependencies
job_dependency_free(j->object_list);
if (other && delete_dependencies) {
job_dependency_free(j->object_list);
if (other && delete_dependencies) {
- log_
debug
("Deleting job %s/%s as dependency of job %s/%s",
+ log_
info
("Deleting job %s/%s as dependency of job %s/%s",
other->unit->meta.id, job_type_to_string(other->type),
j->unit->meta.id, job_type_to_string(j->type));
transaction_delete_job(m, other, delete_dependencies);
other->unit->meta.id, job_type_to_string(other->type),
j->unit->meta.id, job_type_to_string(j->type));
transaction_delete_job(m, other, delete_dependencies);
@@
-1254,6
+1260,7
@@
static int transaction_add_job_and_dependencies(
Job *by,
bool matters,
bool override,
Job *by,
bool matters,
bool override,
+ DBusError *e,
Job **_ret) {
Job *ret;
Iterator i;
Job **_ret) {
Job *ret;
Iterator i;
@@
-1265,11
+1272,15
@@
static int transaction_add_job_and_dependencies(
assert(type < _JOB_TYPE_MAX);
assert(unit);
assert(type < _JOB_TYPE_MAX);
assert(unit);
- if (unit->meta.load_state != UNIT_LOADED)
+ if (unit->meta.load_state != UNIT_LOADED) {
+ dbus_set_error(e, BUS_ERROR_LOAD_FAILED, "Unit %s failed to load. See logs for details.", unit->meta.id);
return -EINVAL;
return -EINVAL;
+ }
- if (!unit_job_is_applicable(unit, type))
+ if (!unit_job_is_applicable(unit, type)) {
+ dbus_set_error(e, BUS_ERROR_JOB_TYPE_NOT_APPLICABLE, "Job type %s is not applicable for unit %s.", job_type_to_string(type), unit->meta.id);
return -EBADR;
return -EBADR;
+ }
/* First add the job. */
if (!(ret = transaction_add_one_job(m, type, unit, override, &is_new)))
/* First add the job. */
if (!(ret = transaction_add_one_job(m, type, unit, override, &is_new)))
@@
-1283,33
+1294,33
@@
static int transaction_add_job_and_dependencies(
/* Finally, recursively add in all dependencies. */
if (type == JOB_START || type == JOB_RELOAD_OR_START) {
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES], i)
/* Finally, recursively add in all dependencies. */
if (type == JOB_START || type == JOB_RELOAD_OR_START) {
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override, NULL)) < 0 && r != -EBADR)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, true, override,
e,
NULL)) < 0 && r != -EBADR)
goto fail;
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRES_OVERRIDABLE], i)
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, NULL)) < 0 && r != -EBADR)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, !override, override,
e,
NULL)) < 0 && r != -EBADR)
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_WANTS], i)
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_WANTS], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false, NULL)) < 0)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_START, dep, ret, false, false,
e,
NULL)) < 0)
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE], i)
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override, NULL)) < 0 && r != -EBADR)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, true, override,
e,
NULL)) < 0 && r != -EBADR)
goto fail;
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
goto fail;
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUISITE_OVERRIDABLE], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override, NULL)) < 0 && r != -EBADR)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_VERIFY_ACTIVE, dep, ret, !override, override,
e,
NULL)) < 0 && r != -EBADR)
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTS], i)
log_warning("Cannot add dependency job for unit %s, ignoring: %s", dep->meta.id, strerror(-r));
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_CONFLICTS], i)
- if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override, NULL)) < 0 && r != -EBADR)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, dep, ret, true, override,
e,
NULL)) < 0 && r != -EBADR)
goto fail;
} else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i)
goto fail;
} else if (type == JOB_STOP || type == JOB_RESTART || type == JOB_TRY_RESTART) {
SET_FOREACH(dep, ret->unit->meta.dependencies[UNIT_REQUIRED_BY], i)
- if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override, NULL)) < 0 && r != -EBADR)
+ if ((r = transaction_add_job_and_dependencies(m, type, dep, ret, true, override,
e,
NULL)) < 0 && r != -EBADR)
goto fail;
}
goto fail;
}
@@
-1343,21
+1354,21
@@
static int transaction_add_isolate_jobs(Manager *m) {
continue;
/* No need to stop inactive jobs */
continue;
/* No need to stop inactive jobs */
- if (
unit_active_state(u) == UNIT_INACTIVE
)
+ if (
UNIT_IS_INACTIVE_OR_MAINTENANCE(unit_active_state(u))
)
continue;
/* Is there already something listed for this? */
if (hashmap_get(m->transaction_jobs, u))
continue;
continue;
/* Is there already something listed for this? */
if (hashmap_get(m->transaction_jobs, u))
continue;
- if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, NULL)) < 0)
+ if ((r = transaction_add_job_and_dependencies(m, JOB_STOP, u, NULL, true, false, NULL
, NULL
)) < 0)
log_warning("Cannot add isolate job for unit %s, ignoring: %s", u->meta.id, strerror(-r));
}
return 0;
}
log_warning("Cannot add isolate job for unit %s, ignoring: %s", u->meta.id, strerror(-r));
}
return 0;
}
-int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override, Job **_ret) {
+int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool override,
DBusError *e,
Job **_ret) {
int r;
Job *ret;
int r;
Job *ret;
@@
-1366,12
+1377,14
@@
int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove
assert(unit);
assert(mode < _JOB_MODE_MAX);
assert(unit);
assert(mode < _JOB_MODE_MAX);
- if (mode == JOB_ISOLATE && type != JOB_START)
+ if (mode == JOB_ISOLATE && type != JOB_START) {
+ dbus_set_error(e, BUS_ERROR_INVALID_JOB_MODE, "Isolate is only valid for start.");
return -EINVAL;
return -EINVAL;
+ }
log_debug("Trying to enqueue job %s/%s", unit->meta.id, job_type_to_string(type));
log_debug("Trying to enqueue job %s/%s", unit->meta.id, job_type_to_string(type));
- if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override, &ret)) < 0) {
+ if ((r = transaction_add_job_and_dependencies(m, type, unit, NULL, true, override,
e,
&ret)) < 0) {
transaction_abort(m);
return r;
}
transaction_abort(m);
return r;
}
@@
-1382,7
+1395,7
@@
int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove
return r;
}
return r;
}
- if ((r = transaction_activate(m, mode)) < 0)
+ if ((r = transaction_activate(m, mode
, e
)) < 0)
return r;
log_debug("Enqueued job %s/%s as %u", unit->meta.id, job_type_to_string(type), (unsigned) ret->id);
return r;
log_debug("Enqueued job %s/%s as %u", unit->meta.id, job_type_to_string(type), (unsigned) ret->id);
@@
-1393,7
+1406,7
@@
int manager_add_job(Manager *m, JobType type, Unit *unit, JobMode mode, bool ove
return 0;
}
return 0;
}
-int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override, Job **_ret) {
+int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode mode, bool override,
DBusError *e,
Job **_ret) {
Unit *unit;
int r;
Unit *unit;
int r;
@@
-1402,10
+1415,10
@@
int manager_add_job_by_name(Manager *m, JobType type, const char *name, JobMode
assert(name);
assert(mode < _JOB_MODE_MAX);
assert(name);
assert(mode < _JOB_MODE_MAX);
- if ((r = manager_load_unit(m, name, NULL, &unit)) < 0)
+ if ((r = manager_load_unit(m, name, NULL,
NULL,
&unit)) < 0)
return r;
return r;
- return manager_add_job(m, type, unit, mode, override, _ret);
+ return manager_add_job(m, type, unit, mode, override,
e,
_ret);
}
Job *manager_get_job(Manager *m, uint32_t id) {
}
Job *manager_get_job(Manager *m, uint32_t id) {
@@
-1447,7
+1460,7
@@
unsigned manager_dispatch_load_queue(Manager *m) {
return n;
}
return n;
}
-int manager_load_unit_prepare(Manager *m, const char *name, const char *path, Unit **_ret) {
+int manager_load_unit_prepare(Manager *m, const char *name, const char *path,
DBusError *e,
Unit **_ret) {
Unit *ret;
int r;
Unit *ret;
int r;
@@
-1457,14
+1470,18
@@
int manager_load_unit_prepare(Manager *m, const char *name, const char *path, Un
/* This will prepare the unit for loading, but not actually
* load anything from disk. */
/* This will prepare the unit for loading, but not actually
* load anything from disk. */
- if (path && !is_path(path))
+ if (path && !is_path(path)) {
+ dbus_set_error(e, BUS_ERROR_INVALID_PATH, "Path %s is not absolute.", path);
return -EINVAL;
return -EINVAL;
+ }
if (!name)
name = file_name_from_path(path);
if (!name)
name = file_name_from_path(path);
- if (!unit_name_is_valid(name))
+ if (!unit_name_is_valid(name)) {
+ dbus_set_error(e, BUS_ERROR_INVALID_NAME, "Unit name %s is not valid.", name);
return -EINVAL;
return -EINVAL;
+ }
if ((ret = manager_get_unit(m, name))) {
*_ret = ret;
if ((ret = manager_get_unit(m, name))) {
*_ret = ret;
@@
-1495,7
+1512,7
@@
int manager_load_unit_prepare(Manager *m, const char *name, const char *path, Un
return 0;
}
return 0;
}
-int manager_load_unit(Manager *m, const char *name, const char *path, Unit **_ret) {
+int manager_load_unit(Manager *m, const char *name, const char *path,
DBusError *e,
Unit **_ret) {
int r;
assert(m);
int r;
assert(m);
@@
-1503,7
+1520,7
@@
int manager_load_unit(Manager *m, const char *name, const char *path, Unit **_re
/* This will load the service information files, but not actually
* start any services or anything. */
/* This will load the service information files, but not actually
* start any services or anything. */
- if ((r = manager_load_unit_prepare(m, name, path, _ret)) != 0)
+ if ((r = manager_load_unit_prepare(m, name, path,
e,
_ret)) != 0)
return r;
manager_dispatch_load_queue(m);
return r;
manager_dispatch_load_queue(m);
@@
-1747,9
+1764,14
@@
static int manager_dispatch_sigchld(Manager *m) {
static int manager_start_target(Manager *m, const char *name, JobMode mode) {
int r;
static int manager_start_target(Manager *m, const char *name, JobMode mode) {
int r;
+ DBusError error;
+
+ dbus_error_init(&error);
+
+ if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, &error, NULL)) < 0)
+ log_error("Failed to enqueue %s job: %s", name, bus_error(&error, r));
- if ((r = manager_add_job_by_name(m, JOB_START, name, mode, true, NULL)) < 0)
- log_error("Failed to enqueue %s job: %s", name, strerror(-r));
+ dbus_error_free(&error);
return r;
}
return r;
}
@@
-1879,7
+1901,7
@@
static int manager_process_signal_fd(Manager *m) {
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(table)) {
manager_start_target(m, table[sfsi.ssi_signo - SIGRTMIN],
if ((int) sfsi.ssi_signo >= SIGRTMIN+0 &&
(int) sfsi.ssi_signo < SIGRTMIN+(int) ELEMENTSOF(table)) {
manager_start_target(m, table[sfsi.ssi_signo - SIGRTMIN],
-
sfsi.ssi_signo == 2
? JOB_ISOLATE : JOB_REPLACE);
+
(sfsi.ssi_signo == 1 || sfsi.ssi_signo == 2)
? JOB_ISOLATE : JOB_REPLACE);
break;
}
break;
}
@@
-2267,7
+2289,7
@@
int manager_deserialize(Manager *m, FILE *f, FDSet *fds) {
char_array_0(name);
char_array_0(name);
- if ((r = manager_load_unit(m, strstrip(name), NULL, &u)) < 0)
+ if ((r = manager_load_unit(m, strstrip(name), NULL,
NULL,
&u)) < 0)
return r;
if ((r = unit_deserialize(u, f, fds)) < 0)
return r;
if ((r = unit_deserialize(u, f, fds)) < 0)
@@
-2336,6
+2358,22
@@
finish:
return r;
}
return r;
}
+bool manager_is_booting_or_shutting_down(Manager *m) {
+ Unit *u;
+
+ assert(m);
+
+ /* Is the initial job still around? */
+ if (manager_get_job(m, 1))
+ return true;
+
+ /* Is there a job for the shutdown target? */
+ if (((u = manager_get_unit(m, SPECIAL_SHUTDOWN_TARGET))))
+ return !!u->meta.job;
+
+ return false;
+}
+
static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
[MANAGER_SYSTEM] = "system",
[MANAGER_SESSION] = "session"
static const char* const manager_running_as_table[_MANAGER_RUNNING_AS_MAX] = {
[MANAGER_SYSTEM] = "system",
[MANAGER_SESSION] = "session"