~ubuntu-branches/ubuntu/trusty/systemd/trusty

« back to all changes in this revision

Viewing changes to src/core/unit.c

Tags: upstream-202
ImportĀ upstreamĀ versionĀ 202

Show diffs side-by-side

added added

removed removed

Lines of Context:
48
48
#include "mkdir.h"
49
49
#include "label.h"
50
50
#include "fileio-label.h"
 
51
#include "bus-errors.h"
51
52
 
52
53
const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX] = {
53
54
        [UNIT_SERVICE] = &service_vtable,
407
408
        strv_free(u->documentation);
408
409
        free(u->fragment_path);
409
410
        free(u->source_path);
 
411
        strv_free(u->dropin_paths);
410
412
        free(u->instance);
411
413
 
412
414
        set_free_free(u->names);
695
697
        if (u->source_path)
696
698
                fprintf(f, "%s\tSource Path: %s\n", prefix, u->source_path);
697
699
 
 
700
        STRV_FOREACH(j, u->dropin_paths)
 
701
                fprintf(f, "%s\tDropIn Path: %s\n", prefix, *j);
 
702
 
698
703
        if (u->job_timeout > 0)
699
 
                fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout));
 
704
                fprintf(f, "%s\tJob Timeout: %s\n", prefix, format_timespan(timespan, sizeof(timespan), u->job_timeout, 0));
700
705
 
701
706
        condition_dump_list(u->conditions, f, prefix);
702
707
 
909
914
        if (u->on_failure_isolate &&
910
915
            set_size(u->dependencies[UNIT_ON_FAILURE]) > 1) {
911
916
 
912
 
                log_error("More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.",
913
 
                          u->id);
 
917
                log_error_unit(u->id,
 
918
                               "More than one OnFailure= dependencies specified for %s but OnFailureIsolate= enabled. Refusing.", u->id);
914
919
 
915
920
                r = -EINVAL;
916
921
                goto fail;
929
934
        unit_add_to_dbus_queue(u);
930
935
        unit_add_to_gc_queue(u);
931
936
 
932
 
        log_debug("Failed to load configuration for %s: %s", u->id, strerror(-r));
 
937
        log_debug_unit(u->id, "Failed to load configuration for %s: %s",
 
938
                       u->id, strerror(-r));
933
939
 
934
940
        return r;
935
941
}
1026
1032
                               SD_MESSAGE_UNIT_RELOADING;
1027
1033
 
1028
1034
        log_struct_unit(LOG_INFO,
1029
 
                   u->id,
1030
 
                   MESSAGE_ID(mid),
1031
 
                   "MESSAGE=%s", buf,
1032
 
                   NULL);
 
1035
                        u->id,
 
1036
                        MESSAGE_ID(mid),
 
1037
                        "MESSAGE=%s", buf,
 
1038
                        NULL);
1033
1039
}
1034
1040
#pragma GCC diagnostic pop
1035
1041
 
1062
1068
         * but we don't want to recheck the condition in that case. */
1063
1069
        if (state != UNIT_ACTIVATING &&
1064
1070
            !unit_condition_test(u)) {
1065
 
                log_debug("Starting of %s requested but condition failed. Ignoring.", u->id);
 
1071
                log_debug_unit(u->id, "Starting of %s requested but condition failed. Ignoring.", u->id);
1066
1072
                return -EALREADY;
1067
1073
        }
1068
1074
 
1069
1075
        /* Forward to the main object, if we aren't it. */
1070
1076
        if ((following = unit_following(u))) {
1071
 
                log_debug("Redirecting start request from %s to %s.", u->id, following->id);
 
1077
                log_debug_unit(u->id, "Redirecting start request from %s to %s.",
 
1078
                               u->id, following->id);
1072
1079
                return unit_start(following);
1073
1080
        }
1074
1081
 
1119
1126
                return -EALREADY;
1120
1127
 
1121
1128
        if ((following = unit_following(u))) {
1122
 
                log_debug("Redirecting stop request from %s to %s.", u->id, following->id);
 
1129
                log_debug_unit(u->id, "Redirecting stop request from %s to %s.",
 
1130
                               u->id, following->id);
1123
1131
                return unit_stop(following);
1124
1132
        }
1125
1133
 
1159
1167
                return -ENOEXEC;
1160
1168
 
1161
1169
        if ((following = unit_following(u))) {
1162
 
                log_debug("Redirecting reload request from %s to %s.", u->id, following->id);
 
1170
                log_debug_unit(u->id, "Redirecting reload request from %s to %s.",
 
1171
                               u->id, following->id);
1163
1172
                return unit_reload(following);
1164
1173
        }
1165
1174
 
1212
1221
                if (unit_pending_active(other))
1213
1222
                        return;
1214
1223
 
1215
 
        log_info("Service %s is not needed anymore. Stopping.", u->id);
 
1224
        log_info_unit(u->id, "Service %s is not needed anymore. Stopping.", u->id);
1216
1225
 
1217
1226
        /* Ok, nobody needs us anymore. Sniff. Then let's commit suicide */
1218
1227
        manager_add_job(u->manager, JOB_STOP, u, JOB_FAIL, true, NULL, NULL);
1240
1249
                    !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1241
1250
                        manager_add_job(u->manager, JOB_START, other, JOB_FAIL, false, NULL, NULL);
1242
1251
 
1243
 
        SET_FOREACH(other, u->dependencies[UNIT_REQUISITE], i)
1244
 
                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1245
 
                    !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1246
 
                        manager_add_job(u->manager, JOB_START, other, JOB_REPLACE, true, NULL, NULL);
1247
 
 
1248
1252
        SET_FOREACH(other, u->dependencies[UNIT_WANTS], i)
1249
1253
                if (!set_get(u->dependencies[UNIT_AFTER], other) &&
1250
1254
                    !UNIT_IS_ACTIVE_OR_ACTIVATING(unit_active_state(other)))
1309
1313
        if (set_size(u->dependencies[UNIT_ON_FAILURE]) <= 0)
1310
1314
                return;
1311
1315
 
1312
 
        log_info("Triggering OnFailure= dependencies of %s.", u->id);
 
1316
        log_info_unit(u->id, "Triggering OnFailure= dependencies of %s.", u->id);
1313
1317
 
1314
1318
        SET_FOREACH(other, u->dependencies[UNIT_ON_FAILURE], i) {
1315
1319
                int r;
1316
1320
 
1317
 
                if ((r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL)) < 0)
1318
 
                        log_error("Failed to enqueue OnFailure= job: %s", strerror(-r));
 
1321
                r = manager_add_job(u->manager, JOB_START, other, u->on_failure_isolate ? JOB_ISOLATE : JOB_REPLACE, true, NULL, NULL);
 
1322
                if (r < 0)
 
1323
                        log_error_unit(u->id, "Failed to enqueue OnFailure= job: %s", strerror(-r));
1319
1324
        }
1320
1325
}
1321
1326
 
1454
1459
                        check_unneeded_dependencies(u);
1455
1460
 
1456
1461
                if (ns != os && ns == UNIT_FAILED) {
1457
 
                        log_struct_unit(LOG_NOTICE,
1458
 
                                   u->id,
1459
 
                                   "MESSAGE=Unit %s entered failed state", u->id,
1460
 
                                   NULL);
 
1462
                        log_notice_unit(u->id,
 
1463
                                        "MESSAGE=Unit %s entered failed state.", u->id);
1461
1464
                        unit_trigger_on_failure(u);
1462
1465
                }
1463
1466
        }
1520
1523
}
1521
1524
 
1522
1525
int unit_watch_fd(Unit *u, int fd, uint32_t events, Watch *w) {
1523
 
        struct epoll_event ev;
 
1526
        struct epoll_event ev = {
 
1527
                .data.ptr = w,
 
1528
                .events = events,
 
1529
        };
1524
1530
 
1525
1531
        assert(u);
1526
1532
        assert(fd >= 0);
1527
1533
        assert(w);
1528
1534
        assert(w->type == WATCH_INVALID || (w->type == WATCH_FD && w->fd == fd && w->data.unit == u));
1529
1535
 
1530
 
        zero(ev);
1531
 
        ev.data.ptr = w;
1532
 
        ev.events = events;
1533
 
 
1534
1536
        if (epoll_ctl(u->manager->epoll_fd,
1535
1537
                      w->type == WATCH_INVALID ? EPOLL_CTL_ADD : EPOLL_CTL_MOD,
1536
1538
                      fd,
1578
1580
}
1579
1581
 
1580
1582
int unit_watch_timer(Unit *u, clockid_t clock_id, bool relative, usec_t usec, Watch *w) {
1581
 
        struct itimerspec its;
 
1583
        struct itimerspec its = {};
1582
1584
        int flags, fd;
1583
1585
        bool ours;
1584
1586
 
1603
1605
        } else
1604
1606
                assert_not_reached("Invalid watch type");
1605
1607
 
1606
 
        zero(its);
1607
 
 
1608
1608
        if (usec <= 0) {
1609
1609
                /* Set absolute time in the past, but not 0, since we
1610
1610
                 * don't want to disarm the timer */
1622
1622
                goto fail;
1623
1623
 
1624
1624
        if (w->type == WATCH_INVALID) {
1625
 
                struct epoll_event ev;
1626
 
 
1627
 
                zero(ev);
1628
 
                ev.data.ptr = w;
1629
 
                ev.events = EPOLLIN;
 
1625
                struct epoll_event ev = {
 
1626
                        .data.ptr = w,
 
1627
                        .events = EPOLLIN,
 
1628
                };
1630
1629
 
1631
1630
                if (epoll_ctl(u->manager->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0)
1632
1631
                        goto fail;
2557
2556
}
2558
2557
 
2559
2558
bool unit_need_daemon_reload(Unit *u) {
 
2559
        _cleanup_strv_free_ char **t = NULL;
 
2560
        char **path;
2560
2561
        struct stat st;
 
2562
        unsigned loaded_cnt, current_cnt;
2561
2563
 
2562
2564
        assert(u);
2563
2565
 
2582
2584
                        return true;
2583
2585
        }
2584
2586
 
2585
 
        return false;
 
2587
        t = unit_find_dropin_paths(u);
 
2588
        loaded_cnt = strv_length(t);
 
2589
        current_cnt = strv_length(u->dropin_paths);
 
2590
 
 
2591
        if (loaded_cnt == current_cnt) {
 
2592
                if (loaded_cnt == 0)
 
2593
                        return false;
 
2594
 
 
2595
                if (strv_overlap(u->dropin_paths, t)) {
 
2596
                        STRV_FOREACH(path, u->dropin_paths) {
 
2597
                                zero(st);
 
2598
                                if (stat(*path, &st) < 0)
 
2599
                                        return true;
 
2600
 
 
2601
                                if (u->dropin_mtime > 0 &&
 
2602
                                    timespec_load(&st.st_mtim) > u->dropin_mtime)
 
2603
                                        return true;
 
2604
                        }
 
2605
 
 
2606
                        return false;
 
2607
                } else
 
2608
                        return true;
 
2609
        } else
 
2610
                return true;
2586
2611
}
2587
2612
 
2588
2613
void unit_reset_failed(Unit *u) {
2644
2669
        return UNIT_VTABLE(u)->kill(u, w, signo, error);
2645
2670
}
2646
2671
 
 
2672
int unit_kill_common(
 
2673
                Unit *u,
 
2674
                KillWho who,
 
2675
                int signo,
 
2676
                pid_t main_pid,
 
2677
                pid_t control_pid,
 
2678
                DBusError *error) {
 
2679
 
 
2680
        int r = 0;
 
2681
 
 
2682
        if (who == KILL_MAIN && main_pid <= 0) {
 
2683
                if (main_pid < 0)
 
2684
                        dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type));
 
2685
                else
 
2686
                        dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill");
 
2687
                return -ESRCH;
 
2688
        }
 
2689
 
 
2690
        if (who == KILL_CONTROL && control_pid <= 0) {
 
2691
                if (control_pid < 0)
 
2692
                        dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type));
 
2693
                else
 
2694
                        dbus_set_error(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill");
 
2695
                return -ESRCH;
 
2696
        }
 
2697
 
 
2698
        if (who == KILL_CONTROL || who == KILL_ALL)
 
2699
                if (control_pid > 0)
 
2700
                        if (kill(control_pid, signo) < 0)
 
2701
                                r = -errno;
 
2702
 
 
2703
        if (who == KILL_MAIN || who == KILL_ALL)
 
2704
                if (main_pid > 0)
 
2705
                        if (kill(main_pid, signo) < 0)
 
2706
                                r = -errno;
 
2707
 
 
2708
        if (who == KILL_ALL) {
 
2709
                _cleanup_set_free_ Set *pid_set = NULL;
 
2710
                int q;
 
2711
 
 
2712
                pid_set = set_new(trivial_hash_func, trivial_compare_func);
 
2713
                if (!pid_set)
 
2714
                        return -ENOMEM;
 
2715
 
 
2716
                /* Exclude the control/main pid from being killed via the cgroup */
 
2717
                if (control_pid > 0) {
 
2718
                        q = set_put(pid_set, LONG_TO_PTR(control_pid));
 
2719
                        if (q < 0)
 
2720
                                return q;
 
2721
                }
 
2722
 
 
2723
                if (main_pid > 0) {
 
2724
                        q = set_put(pid_set, LONG_TO_PTR(main_pid));
 
2725
                        if (q < 0)
 
2726
                                return q;
 
2727
                }
 
2728
 
 
2729
                q = cgroup_bonding_kill_list(u->cgroup_bondings, signo, false, false, pid_set, NULL);
 
2730
                if (q < 0 && q != -EAGAIN && q != -ESRCH && q != -ENOENT)
 
2731
                        r = q;
 
2732
        }
 
2733
 
 
2734
        return r;
 
2735
}
 
2736
 
2647
2737
int unit_following_set(Unit *u, Set **s) {
2648
2738
        assert(u);
2649
2739
        assert(s);
2819
2909
                return r;
2820
2910
 
2821
2911
        mkdir_p(p, 0755);
2822
 
        return write_one_line_file_atomic_label(q, data);
 
2912
        return write_string_file_atomic_label(q, data);
2823
2913
}
2824
2914
 
2825
2915
int unit_remove_drop_in(Unit *u, bool runtime, const char *name) {