| File: | build-scan/../src/login/logind-user.c |
| Warning: | line 53, column 25 Potential leak of memory pointed to by 'u' |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
| 1 | /* SPDX-License-Identifier: LGPL-2.1+ */ | |||
| 2 | ||||
| 3 | #include <errno(*__errno_location ()).h> | |||
| 4 | #include <string.h> | |||
| 5 | #include <unistd.h> | |||
| 6 | #include <stdio_ext.h> | |||
| 7 | ||||
| 8 | #include "alloc-util.h" | |||
| 9 | #include "bus-common-errors.h" | |||
| 10 | #include "bus-error.h" | |||
| 11 | #include "bus-util.h" | |||
| 12 | #include "cgroup-util.h" | |||
| 13 | #include "clean-ipc.h" | |||
| 14 | #include "escape.h" | |||
| 15 | #include "fd-util.h" | |||
| 16 | #include "fileio.h" | |||
| 17 | #include "format-util.h" | |||
| 18 | #include "fs-util.h" | |||
| 19 | #include "hashmap.h" | |||
| 20 | #include "label.h" | |||
| 21 | #include "logind-user.h" | |||
| 22 | #include "mkdir.h" | |||
| 23 | #include "parse-util.h" | |||
| 24 | #include "path-util.h" | |||
| 25 | #include "rm-rf.h" | |||
| 26 | #include "special.h" | |||
| 27 | #include "stdio-util.h" | |||
| 28 | #include "string-table.h" | |||
| 29 | #include "unit-name.h" | |||
| 30 | #include "user-util.h" | |||
| 31 | #include "util.h" | |||
| 32 | ||||
| 33 | int user_new(User **out, Manager *m, uid_t uid, gid_t gid, const char *name) { | |||
| 34 | _cleanup_(user_freep)__attribute__((cleanup(user_freep))) User *u = NULL((void*)0); | |||
| 35 | char lu[DECIMAL_STR_MAX(uid_t)(2+(sizeof(uid_t) <= 1 ? 3 : sizeof(uid_t) <= 2 ? 5 : sizeof (uid_t) <= 4 ? 10 : sizeof(uid_t) <= 8 ? 20 : sizeof(int [-2*(sizeof(uid_t) > 8)]))) + 1]; | |||
| 36 | int r; | |||
| 37 | ||||
| 38 | assert(out)do { if ((__builtin_expect(!!(!(out)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("out"), "../src/login/logind-user.c", 38 , __PRETTY_FUNCTION__); } while (0); | |||
| ||||
| 39 | assert(m)do { if ((__builtin_expect(!!(!(m)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("m"), "../src/login/logind-user.c", 39, __PRETTY_FUNCTION__ ); } while (0); | |||
| 40 | assert(name)do { if ((__builtin_expect(!!(!(name)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("name"), "../src/login/logind-user.c", 40 , __PRETTY_FUNCTION__); } while (0); | |||
| 41 | ||||
| 42 | u = new0(User, 1)((User*) calloc((1), sizeof(User))); | |||
| 43 | if (!u) | |||
| 44 | return -ENOMEM12; | |||
| 45 | ||||
| 46 | u->manager = m; | |||
| 47 | u->uid = uid; | |||
| 48 | u->gid = gid; | |||
| 49 | xsprintf(lu, UID_FMT, uid)do { if ((__builtin_expect(!!(!(((size_t) snprintf(lu, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p(typeof (lu), typeof(&*(lu))), sizeof(lu)/sizeof((lu)[0]), ((void )0))), "%" "u", uid) < (__extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(lu), typeof(&*(lu) )), sizeof(lu)/sizeof((lu)[0]), ((void)0))))))),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("xsprintf: " "lu" "[] must be big enough" ), "../src/login/logind-user.c", 49, __PRETTY_FUNCTION__); } while (0); | |||
| 50 | ||||
| 51 | u->name = strdup(name); | |||
| 52 | if (!u->name) | |||
| 53 | return -ENOMEM12; | |||
| ||||
| 54 | ||||
| 55 | if (asprintf(&u->state_file, "/run/systemd/users/"UID_FMT"%" "u", uid) < 0) | |||
| 56 | return -ENOMEM12; | |||
| 57 | ||||
| 58 | if (asprintf(&u->runtime_path, "/run/user/"UID_FMT"%" "u", uid) < 0) | |||
| 59 | return -ENOMEM12; | |||
| 60 | ||||
| 61 | r = slice_build_subslice(SPECIAL_USER_SLICE"user.slice", lu, &u->slice); | |||
| 62 | if (r < 0) | |||
| 63 | return r; | |||
| 64 | ||||
| 65 | r = unit_name_build("user", lu, ".service", &u->service); | |||
| 66 | if (r < 0) | |||
| 67 | return r; | |||
| 68 | ||||
| 69 | r = hashmap_put(m->users, UID_TO_PTR(uid)((void*) (((uintptr_t) (uid))+1)), u); | |||
| 70 | if (r < 0) | |||
| 71 | return r; | |||
| 72 | ||||
| 73 | r = hashmap_put(m->user_units, u->slice, u); | |||
| 74 | if (r < 0) | |||
| 75 | return r; | |||
| 76 | ||||
| 77 | r = hashmap_put(m->user_units, u->service, u); | |||
| 78 | if (r < 0) | |||
| 79 | return r; | |||
| 80 | ||||
| 81 | *out = TAKE_PTR(u)({ typeof(u) _ptr_ = (u); (u) = ((void*)0); _ptr_; }); | |||
| 82 | ||||
| 83 | return 0; | |||
| 84 | } | |||
| 85 | ||||
| 86 | User *user_free(User *u) { | |||
| 87 | if (!u) | |||
| 88 | return NULL((void*)0); | |||
| 89 | ||||
| 90 | if (u->in_gc_queue) | |||
| 91 | LIST_REMOVE(gc_queue, u->manager->user_gc_queue, u)do { typeof(*(u->manager->user_gc_queue)) **_head = & (u->manager->user_gc_queue), *_item = (u); do { if ((__builtin_expect (!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/login/logind-user.c", 91, __PRETTY_FUNCTION__ ); } while (0); if (_item->gc_queue_next) _item->gc_queue_next ->gc_queue_prev = _item->gc_queue_prev; if (_item->gc_queue_prev ) _item->gc_queue_prev->gc_queue_next = _item->gc_queue_next ; else { do { if ((__builtin_expect(!!(!(*_head == _item)),0) )) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("*_head == _item" ), "../src/login/logind-user.c", 91, __PRETTY_FUNCTION__); } while (0); *_head = _item->gc_queue_next; } _item->gc_queue_next = _item->gc_queue_prev = ((void*)0); } while (0); | |||
| 92 | ||||
| 93 | while (u->sessions) | |||
| 94 | session_free(u->sessions); | |||
| 95 | ||||
| 96 | if (u->service) | |||
| 97 | hashmap_remove_value(u->manager->user_units, u->service, u); | |||
| 98 | ||||
| 99 | if (u->slice) | |||
| 100 | hashmap_remove_value(u->manager->user_units, u->slice, u); | |||
| 101 | ||||
| 102 | hashmap_remove_value(u->manager->users, UID_TO_PTR(u->uid)((void*) (((uintptr_t) (u->uid))+1)), u); | |||
| 103 | ||||
| 104 | u->slice_job = mfree(u->slice_job); | |||
| 105 | u->service_job = mfree(u->service_job); | |||
| 106 | ||||
| 107 | u->service = mfree(u->service); | |||
| 108 | u->slice = mfree(u->slice); | |||
| 109 | u->runtime_path = mfree(u->runtime_path); | |||
| 110 | u->state_file = mfree(u->state_file); | |||
| 111 | u->name = mfree(u->name); | |||
| 112 | ||||
| 113 | return mfree(u); | |||
| 114 | } | |||
| 115 | ||||
| 116 | static int user_save_internal(User *u) { | |||
| 117 | _cleanup_free___attribute__((cleanup(freep))) char *temp_path = NULL((void*)0); | |||
| 118 | _cleanup_fclose___attribute__((cleanup(fclosep))) FILE *f = NULL((void*)0); | |||
| 119 | int r; | |||
| 120 | ||||
| 121 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 121, __PRETTY_FUNCTION__); } while (0); | |||
| 122 | assert(u->state_file)do { if ((__builtin_expect(!!(!(u->state_file)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u->state_file"), "../src/login/logind-user.c" , 122, __PRETTY_FUNCTION__); } while (0); | |||
| 123 | ||||
| 124 | r = mkdir_safe_label("/run/systemd/users", 0755, 0, 0, MKDIR_WARN_MODE); | |||
| 125 | if (r < 0) | |||
| 126 | goto fail; | |||
| 127 | ||||
| 128 | r = fopen_temporary(u->state_file, &f, &temp_path); | |||
| 129 | if (r < 0) | |||
| 130 | goto fail; | |||
| 131 | ||||
| 132 | (void) __fsetlocking(f, FSETLOCKING_BYCALLERFSETLOCKING_BYCALLER); | |||
| 133 | (void) fchmod(fileno(f), 0644); | |||
| 134 | ||||
| 135 | fprintf(f, | |||
| 136 | "# This is private data. Do not parse.\n" | |||
| 137 | "NAME=%s\n" | |||
| 138 | "STATE=%s\n", | |||
| 139 | u->name, | |||
| 140 | user_state_to_string(user_get_state(u))); | |||
| 141 | ||||
| 142 | /* LEGACY: no-one reads RUNTIME= anymore, drop it at some point */ | |||
| 143 | if (u->runtime_path) | |||
| 144 | fprintf(f, "RUNTIME=%s\n", u->runtime_path); | |||
| 145 | ||||
| 146 | if (u->service_job) | |||
| 147 | fprintf(f, "SERVICE_JOB=%s\n", u->service_job); | |||
| 148 | ||||
| 149 | if (u->slice_job) | |||
| 150 | fprintf(f, "SLICE_JOB=%s\n", u->slice_job); | |||
| 151 | ||||
| 152 | if (u->display) | |||
| 153 | fprintf(f, "DISPLAY=%s\n", u->display->id); | |||
| 154 | ||||
| 155 | if (dual_timestamp_is_set(&u->timestamp)) | |||
| 156 | fprintf(f, | |||
| 157 | "REALTIME="USEC_FMT"%" "l" "u""\n" | |||
| 158 | "MONOTONIC="USEC_FMT"%" "l" "u""\n", | |||
| 159 | u->timestamp.realtime, | |||
| 160 | u->timestamp.monotonic); | |||
| 161 | ||||
| 162 | if (u->sessions) { | |||
| 163 | Session *i; | |||
| 164 | bool_Bool first; | |||
| 165 | ||||
| 166 | fputs("SESSIONS=", f); | |||
| 167 | first = true1; | |||
| 168 | LIST_FOREACH(sessions_by_user, i, u->sessions)for ((i) = (u->sessions); (i); (i) = (i)->sessions_by_user_next ) { | |||
| 169 | if (first) | |||
| 170 | first = false0; | |||
| 171 | else | |||
| 172 | fputc(' ', f); | |||
| 173 | ||||
| 174 | fputs(i->id, f); | |||
| 175 | } | |||
| 176 | ||||
| 177 | fputs("\nSEATS=", f); | |||
| 178 | first = true1; | |||
| 179 | LIST_FOREACH(sessions_by_user, i, u->sessions)for ((i) = (u->sessions); (i); (i) = (i)->sessions_by_user_next ) { | |||
| 180 | if (!i->seat) | |||
| 181 | continue; | |||
| 182 | ||||
| 183 | if (first) | |||
| 184 | first = false0; | |||
| 185 | else | |||
| 186 | fputc(' ', f); | |||
| 187 | ||||
| 188 | fputs(i->seat->id, f); | |||
| 189 | } | |||
| 190 | ||||
| 191 | fputs("\nACTIVE_SESSIONS=", f); | |||
| 192 | first = true1; | |||
| 193 | LIST_FOREACH(sessions_by_user, i, u->sessions)for ((i) = (u->sessions); (i); (i) = (i)->sessions_by_user_next ) { | |||
| 194 | if (!session_is_active(i)) | |||
| 195 | continue; | |||
| 196 | ||||
| 197 | if (first) | |||
| 198 | first = false0; | |||
| 199 | else | |||
| 200 | fputc(' ', f); | |||
| 201 | ||||
| 202 | fputs(i->id, f); | |||
| 203 | } | |||
| 204 | ||||
| 205 | fputs("\nONLINE_SESSIONS=", f); | |||
| 206 | first = true1; | |||
| 207 | LIST_FOREACH(sessions_by_user, i, u->sessions)for ((i) = (u->sessions); (i); (i) = (i)->sessions_by_user_next ) { | |||
| 208 | if (session_get_state(i) == SESSION_CLOSING) | |||
| 209 | continue; | |||
| 210 | ||||
| 211 | if (first) | |||
| 212 | first = false0; | |||
| 213 | else | |||
| 214 | fputc(' ', f); | |||
| 215 | ||||
| 216 | fputs(i->id, f); | |||
| 217 | } | |||
| 218 | ||||
| 219 | fputs("\nACTIVE_SEATS=", f); | |||
| 220 | first = true1; | |||
| 221 | LIST_FOREACH(sessions_by_user, i, u->sessions)for ((i) = (u->sessions); (i); (i) = (i)->sessions_by_user_next ) { | |||
| 222 | if (!session_is_active(i) || !i->seat) | |||
| 223 | continue; | |||
| 224 | ||||
| 225 | if (first) | |||
| 226 | first = false0; | |||
| 227 | else | |||
| 228 | fputc(' ', f); | |||
| 229 | ||||
| 230 | fputs(i->seat->id, f); | |||
| 231 | } | |||
| 232 | ||||
| 233 | fputs("\nONLINE_SEATS=", f); | |||
| 234 | first = true1; | |||
| 235 | LIST_FOREACH(sessions_by_user, i, u->sessions)for ((i) = (u->sessions); (i); (i) = (i)->sessions_by_user_next ) { | |||
| 236 | if (session_get_state(i) == SESSION_CLOSING || !i->seat) | |||
| 237 | continue; | |||
| 238 | ||||
| 239 | if (first) | |||
| 240 | first = false0; | |||
| 241 | else | |||
| 242 | fputc(' ', f); | |||
| 243 | ||||
| 244 | fputs(i->seat->id, f); | |||
| 245 | } | |||
| 246 | fputc('\n', f); | |||
| 247 | } | |||
| 248 | ||||
| 249 | r = fflush_and_check(f); | |||
| 250 | if (r < 0) | |||
| 251 | goto fail; | |||
| 252 | ||||
| 253 | if (rename(temp_path, u->state_file) < 0) { | |||
| 254 | r = -errno(*__errno_location ()); | |||
| 255 | goto fail; | |||
| 256 | } | |||
| 257 | ||||
| 258 | return 0; | |||
| 259 | ||||
| 260 | fail: | |||
| 261 | (void) unlink(u->state_file); | |||
| 262 | ||||
| 263 | if (temp_path) | |||
| 264 | (void) unlink(temp_path); | |||
| 265 | ||||
| 266 | return log_error_errno(r, "Failed to save user data %s: %m", u->state_file)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 266, __func__, "Failed to save user data %s: %m" , u->state_file) : -abs(_e); }); | |||
| 267 | } | |||
| 268 | ||||
| 269 | int user_save(User *u) { | |||
| 270 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 270, __PRETTY_FUNCTION__); } while (0); | |||
| 271 | ||||
| 272 | if (!u->started) | |||
| 273 | return 0; | |||
| 274 | ||||
| 275 | return user_save_internal (u); | |||
| 276 | } | |||
| 277 | ||||
| 278 | int user_load(User *u) { | |||
| 279 | _cleanup_free___attribute__((cleanup(freep))) char *display = NULL((void*)0), *realtime = NULL((void*)0), *monotonic = NULL((void*)0); | |||
| 280 | Session *s = NULL((void*)0); | |||
| 281 | int r; | |||
| 282 | ||||
| 283 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 283, __PRETTY_FUNCTION__); } while (0); | |||
| 284 | ||||
| 285 | r = parse_env_file(NULL((void*)0), u->state_file, NEWLINE"\n\r", | |||
| 286 | "SERVICE_JOB", &u->service_job, | |||
| 287 | "SLICE_JOB", &u->slice_job, | |||
| 288 | "DISPLAY", &display, | |||
| 289 | "REALTIME", &realtime, | |||
| 290 | "MONOTONIC", &monotonic, | |||
| 291 | NULL((void*)0)); | |||
| 292 | if (r < 0) { | |||
| 293 | if (r == -ENOENT2) | |||
| 294 | return 0; | |||
| 295 | ||||
| 296 | return log_error_errno(r, "Failed to read %s: %m", u->state_file)({ int _level = ((3)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 296, __func__, "Failed to read %s: %m" , u->state_file) : -abs(_e); }); | |||
| 297 | } | |||
| 298 | ||||
| 299 | if (display) | |||
| 300 | s = hashmap_get(u->manager->sessions, display); | |||
| 301 | ||||
| 302 | if (s && s->display && display_is_local(s->display)) | |||
| 303 | u->display = s; | |||
| 304 | ||||
| 305 | if (realtime) | |||
| 306 | timestamp_deserialize(realtime, &u->timestamp.realtime); | |||
| 307 | if (monotonic) | |||
| 308 | timestamp_deserialize(monotonic, &u->timestamp.monotonic); | |||
| 309 | ||||
| 310 | return r; | |||
| 311 | } | |||
| 312 | ||||
| 313 | static int user_start_service(User *u) { | |||
| 314 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
| 315 | char *job; | |||
| 316 | int r; | |||
| 317 | ||||
| 318 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 318, __PRETTY_FUNCTION__); } while (0); | |||
| 319 | ||||
| 320 | u->service_job = mfree(u->service_job); | |||
| 321 | ||||
| 322 | r = manager_start_unit( | |||
| 323 | u->manager, | |||
| 324 | u->service, | |||
| 325 | &error, | |||
| 326 | &job); | |||
| 327 | if (r < 0) | |||
| 328 | /* we don't fail due to this, let's try to continue */ | |||
| 329 | log_full_errno(sd_bus_error_has_name(&error, BUS_ERROR_UNIT_MASKED) ? LOG_DEBUG : LOG_WARNING, r,({ int _level = ((sd_bus_error_has_name(&error, "org.freedesktop.systemd1.UnitMasked" ) ? 7 : 4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm (_realm) >= ((_level) & 0x07)) ? log_internal_realm((( _realm) << 10 | (_level)), _e, "../src/login/logind-user.c" , 330, __func__, "Failed to start user service '%s', ignoring: %s" , u->service, bus_error_message(&error, r)) : -abs(_e) ; }) | |||
| 330 | "Failed to start user service '%s', ignoring: %s", u->service, bus_error_message(&error, r))({ int _level = ((sd_bus_error_has_name(&error, "org.freedesktop.systemd1.UnitMasked" ) ? 7 : 4)), _e = ((r)), _realm = (LOG_REALM_SYSTEMD); (log_get_max_level_realm (_realm) >= ((_level) & 0x07)) ? log_internal_realm((( _realm) << 10 | (_level)), _e, "../src/login/logind-user.c" , 330, __func__, "Failed to start user service '%s', ignoring: %s" , u->service, bus_error_message(&error, r)) : -abs(_e) ; }); | |||
| 331 | else | |||
| 332 | u->service_job = job; | |||
| 333 | ||||
| 334 | return 0; | |||
| 335 | } | |||
| 336 | ||||
| 337 | int user_start(User *u) { | |||
| 338 | int r; | |||
| 339 | ||||
| 340 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 340, __PRETTY_FUNCTION__); } while (0); | |||
| 341 | ||||
| 342 | if (u->started && !u->stopping) | |||
| 343 | return 0; | |||
| 344 | ||||
| 345 | /* | |||
| 346 | * If u->stopping is set, the user is marked for removal and the slice | |||
| 347 | * and service stop-jobs are queued. We have to clear that flag before | |||
| 348 | * queing the start-jobs again. If they succeed, the user object can be | |||
| 349 | * re-used just fine (pid1 takes care of job-ordering and proper | |||
| 350 | * restart), but if they fail, we want to force another user_stop() so | |||
| 351 | * possibly pending units are stopped. | |||
| 352 | * Note that we don't clear u->started, as we have no clue what state | |||
| 353 | * the user is in on failure here. Hence, we pretend the user is | |||
| 354 | * running so it will be properly taken down by GC. However, we clearly | |||
| 355 | * return an error from user_start() in that case, so no further | |||
| 356 | * reference to the user is taken. | |||
| 357 | */ | |||
| 358 | u->stopping = false0; | |||
| 359 | ||||
| 360 | if (!u->started) | |||
| 361 | log_debug("Starting services for new user %s.", u->name)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 361, __func__, "Starting services for new user %s." , u->name) : -abs(_e); }); | |||
| 362 | ||||
| 363 | /* Save the user data so far, because pam_systemd will read the | |||
| 364 | * XDG_RUNTIME_DIR out of it while starting up systemd --user. | |||
| 365 | * We need to do user_save_internal() because we have not | |||
| 366 | * "officially" started yet. */ | |||
| 367 | user_save_internal(u); | |||
| 368 | ||||
| 369 | /* Spawn user systemd */ | |||
| 370 | r = user_start_service(u); | |||
| 371 | if (r < 0) | |||
| 372 | return r; | |||
| 373 | ||||
| 374 | if (!u->started) { | |||
| 375 | if (!dual_timestamp_is_set(&u->timestamp)) | |||
| 376 | dual_timestamp_get(&u->timestamp); | |||
| 377 | user_send_signal(u, true1); | |||
| 378 | u->started = true1; | |||
| 379 | } | |||
| 380 | ||||
| 381 | /* Save new user data */ | |||
| 382 | user_save(u); | |||
| 383 | ||||
| 384 | return 0; | |||
| 385 | } | |||
| 386 | ||||
| 387 | static int user_stop_slice(User *u) { | |||
| 388 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
| 389 | char *job; | |||
| 390 | int r; | |||
| 391 | ||||
| 392 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 392, __PRETTY_FUNCTION__); } while (0); | |||
| 393 | ||||
| 394 | r = manager_stop_unit(u->manager, u->slice, &error, &job); | |||
| 395 | if (r < 0) { | |||
| 396 | log_error("Failed to stop user slice: %s", bus_error_message(&error, r))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 396, __func__, "Failed to stop user slice: %s" , bus_error_message(&error, r)) : -abs(_e); }); | |||
| 397 | return r; | |||
| 398 | } | |||
| 399 | ||||
| 400 | free(u->slice_job); | |||
| 401 | u->slice_job = job; | |||
| 402 | ||||
| 403 | return r; | |||
| 404 | } | |||
| 405 | ||||
| 406 | static int user_stop_service(User *u) { | |||
| 407 | _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0}); | |||
| 408 | char *job; | |||
| 409 | int r; | |||
| 410 | ||||
| 411 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 411, __PRETTY_FUNCTION__); } while (0); | |||
| 412 | ||||
| 413 | r = manager_stop_unit(u->manager, u->service, &error, &job); | |||
| 414 | if (r < 0) { | |||
| 415 | log_error("Failed to stop user service: %s", bus_error_message(&error, r))({ int _level = (((3))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 415, __func__, "Failed to stop user service: %s" , bus_error_message(&error, r)) : -abs(_e); }); | |||
| 416 | return r; | |||
| 417 | } | |||
| 418 | ||||
| 419 | free_and_replace(u->service_job, job)({ free(u->service_job); (u->service_job) = (job); (job ) = ((void*)0); 0; }); | |||
| 420 | return r; | |||
| 421 | } | |||
| 422 | ||||
| 423 | int user_stop(User *u, bool_Bool force) { | |||
| 424 | Session *s; | |||
| 425 | int r = 0, k; | |||
| 426 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 426, __PRETTY_FUNCTION__); } while (0); | |||
| 427 | ||||
| 428 | /* Stop jobs have already been queued */ | |||
| 429 | if (u->stopping) { | |||
| 430 | user_save(u); | |||
| 431 | return r; | |||
| 432 | } | |||
| 433 | ||||
| 434 | LIST_FOREACH(sessions_by_user, s, u->sessions)for ((s) = (u->sessions); (s); (s) = (s)->sessions_by_user_next ) { | |||
| 435 | k = session_stop(s, force); | |||
| 436 | if (k < 0) | |||
| 437 | r = k; | |||
| 438 | } | |||
| 439 | ||||
| 440 | /* Kill systemd */ | |||
| 441 | k = user_stop_service(u); | |||
| 442 | if (k < 0) | |||
| 443 | r = k; | |||
| 444 | ||||
| 445 | /* Kill cgroup */ | |||
| 446 | k = user_stop_slice(u); | |||
| 447 | if (k < 0) | |||
| 448 | r = k; | |||
| 449 | ||||
| 450 | u->stopping = true1; | |||
| 451 | ||||
| 452 | user_save(u); | |||
| 453 | ||||
| 454 | return r; | |||
| 455 | } | |||
| 456 | ||||
| 457 | int user_finalize(User *u) { | |||
| 458 | Session *s; | |||
| 459 | int r = 0, k; | |||
| 460 | ||||
| 461 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 461, __PRETTY_FUNCTION__); } while (0); | |||
| 462 | ||||
| 463 | if (u->started) | |||
| 464 | log_debug("User %s logged out.", u->name)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 464, __func__, "User %s logged out." , u->name) : -abs(_e); }); | |||
| 465 | ||||
| 466 | LIST_FOREACH(sessions_by_user, s, u->sessions)for ((s) = (u->sessions); (s); (s) = (s)->sessions_by_user_next ) { | |||
| 467 | k = session_finalize(s); | |||
| 468 | if (k < 0) | |||
| 469 | r = k; | |||
| 470 | } | |||
| 471 | ||||
| 472 | /* Clean SysV + POSIX IPC objects, but only if this is not a system user. Background: in many setups cronjobs | |||
| 473 | * are run in full PAM and thus logind sessions, even if the code run doesn't belong to actual users but to | |||
| 474 | * system components. Since enable RemoveIPC= globally for all users, we need to be a bit careful with such | |||
| 475 | * cases, as we shouldn't accidentally remove a system service's IPC objects while it is running, just because | |||
| 476 | * a cronjob running as the same user just finished. Hence: exclude system users generally from IPC clean-up, | |||
| 477 | * and do it only for normal users. */ | |||
| 478 | if (u->manager->remove_ipc && !uid_is_system(u->uid)) { | |||
| 479 | k = clean_ipc_by_uid(u->uid); | |||
| 480 | if (k < 0) | |||
| 481 | r = k; | |||
| 482 | } | |||
| 483 | ||||
| 484 | unlink(u->state_file); | |||
| 485 | user_add_to_gc_queue(u); | |||
| 486 | ||||
| 487 | if (u->started) { | |||
| 488 | user_send_signal(u, false0); | |||
| 489 | u->started = false0; | |||
| 490 | } | |||
| 491 | ||||
| 492 | return r; | |||
| 493 | } | |||
| 494 | ||||
| 495 | int user_get_idle_hint(User *u, dual_timestamp *t) { | |||
| 496 | Session *s; | |||
| 497 | bool_Bool idle_hint = true1; | |||
| 498 | dual_timestamp ts = DUAL_TIMESTAMP_NULL((struct dual_timestamp) {}); | |||
| 499 | ||||
| 500 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 500, __PRETTY_FUNCTION__); } while (0); | |||
| 501 | ||||
| 502 | LIST_FOREACH(sessions_by_user, s, u->sessions)for ((s) = (u->sessions); (s); (s) = (s)->sessions_by_user_next ) { | |||
| 503 | dual_timestamp k; | |||
| 504 | int ih; | |||
| 505 | ||||
| 506 | ih = session_get_idle_hint(s, &k); | |||
| 507 | if (ih < 0) | |||
| 508 | return ih; | |||
| 509 | ||||
| 510 | if (!ih) { | |||
| 511 | if (!idle_hint) { | |||
| 512 | if (k.monotonic < ts.monotonic) | |||
| 513 | ts = k; | |||
| 514 | } else { | |||
| 515 | idle_hint = false0; | |||
| 516 | ts = k; | |||
| 517 | } | |||
| 518 | } else if (idle_hint) { | |||
| 519 | ||||
| 520 | if (k.monotonic > ts.monotonic) | |||
| 521 | ts = k; | |||
| 522 | } | |||
| 523 | } | |||
| 524 | ||||
| 525 | if (t) | |||
| 526 | *t = ts; | |||
| 527 | ||||
| 528 | return idle_hint; | |||
| 529 | } | |||
| 530 | ||||
| 531 | int user_check_linger_file(User *u) { | |||
| 532 | _cleanup_free___attribute__((cleanup(freep))) char *cc = NULL((void*)0); | |||
| 533 | char *p = NULL((void*)0); | |||
| 534 | ||||
| 535 | cc = cescape(u->name); | |||
| 536 | if (!cc) | |||
| 537 | return -ENOMEM12; | |||
| 538 | ||||
| 539 | p = strjoina("/var/lib/systemd/linger/", cc)({ const char *_appendees_[] = { "/var/lib/systemd/linger/", cc }; char *_d_, *_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_ )/sizeof((_appendees_)[0]), ((void)0))) && _appendees_ [_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr ( !__builtin_types_compatible_p(typeof(_appendees_), typeof(& *(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0] ), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy (_p_, _appendees_[_i_]); *_p_ = 0; _d_; }); | |||
| 540 | ||||
| 541 | return access(p, F_OK0) >= 0; | |||
| 542 | } | |||
| 543 | ||||
| 544 | bool_Bool user_may_gc(User *u, bool_Bool drop_not_started) { | |||
| 545 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 545, __PRETTY_FUNCTION__); } while (0); | |||
| 546 | ||||
| 547 | if (drop_not_started && !u->started) | |||
| 548 | return true1; | |||
| 549 | ||||
| 550 | if (u->sessions) | |||
| 551 | return false0; | |||
| 552 | ||||
| 553 | if (user_check_linger_file(u) > 0) | |||
| 554 | return false0; | |||
| 555 | ||||
| 556 | if (u->slice_job && manager_job_is_active(u->manager, u->slice_job)) | |||
| 557 | return false0; | |||
| 558 | ||||
| 559 | if (u->service_job && manager_job_is_active(u->manager, u->service_job)) | |||
| 560 | return false0; | |||
| 561 | ||||
| 562 | return true1; | |||
| 563 | } | |||
| 564 | ||||
| 565 | void user_add_to_gc_queue(User *u) { | |||
| 566 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 566, __PRETTY_FUNCTION__); } while (0); | |||
| 567 | ||||
| 568 | if (u->in_gc_queue) | |||
| 569 | return; | |||
| 570 | ||||
| 571 | LIST_PREPEND(gc_queue, u->manager->user_gc_queue, u)do { typeof(*(u->manager->user_gc_queue)) **_head = & (u->manager->user_gc_queue), *_item = (u); do { if ((__builtin_expect (!!(!(_item)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("_item"), "../src/login/logind-user.c", 571, __PRETTY_FUNCTION__ ); } while (0); if ((_item->gc_queue_next = *_head)) _item ->gc_queue_next->gc_queue_prev = _item; _item->gc_queue_prev = ((void*)0); *_head = _item; } while (0); | |||
| 572 | u->in_gc_queue = true1; | |||
| 573 | } | |||
| 574 | ||||
| 575 | UserState user_get_state(User *u) { | |||
| 576 | Session *i; | |||
| 577 | ||||
| 578 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 578, __PRETTY_FUNCTION__); } while (0); | |||
| 579 | ||||
| 580 | if (u->stopping) | |||
| 581 | return USER_CLOSING; | |||
| 582 | ||||
| 583 | if (!u->started || u->slice_job || u->service_job) | |||
| 584 | return USER_OPENING; | |||
| 585 | ||||
| 586 | if (u->sessions) { | |||
| 587 | bool_Bool all_closing = true1; | |||
| 588 | ||||
| 589 | LIST_FOREACH(sessions_by_user, i, u->sessions)for ((i) = (u->sessions); (i); (i) = (i)->sessions_by_user_next ) { | |||
| 590 | SessionState state; | |||
| 591 | ||||
| 592 | state = session_get_state(i); | |||
| 593 | if (state == SESSION_ACTIVE) | |||
| 594 | return USER_ACTIVE; | |||
| 595 | if (state != SESSION_CLOSING) | |||
| 596 | all_closing = false0; | |||
| 597 | } | |||
| 598 | ||||
| 599 | return all_closing ? USER_CLOSING : USER_ONLINE; | |||
| 600 | } | |||
| 601 | ||||
| 602 | if (user_check_linger_file(u) > 0) | |||
| 603 | return USER_LINGERING; | |||
| 604 | ||||
| 605 | return USER_CLOSING; | |||
| 606 | } | |||
| 607 | ||||
| 608 | int user_kill(User *u, int signo) { | |||
| 609 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 609, __PRETTY_FUNCTION__); } while (0); | |||
| 610 | ||||
| 611 | return manager_kill_unit(u->manager, u->slice, KILL_ALL, signo, NULL((void*)0)); | |||
| 612 | } | |||
| 613 | ||||
| 614 | static bool_Bool elect_display_filter(Session *s) { | |||
| 615 | /* Return true if the session is a candidate for the user’s ‘primary | |||
| 616 | * session’ or ‘display’. */ | |||
| 617 | assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("s"), "../src/login/logind-user.c", 617, __PRETTY_FUNCTION__); } while (0); | |||
| 618 | ||||
| 619 | return (s->class == SESSION_USER && !s->stopping); | |||
| 620 | } | |||
| 621 | ||||
| 622 | static int elect_display_compare(Session *s1, Session *s2) { | |||
| 623 | /* Indexed by SessionType. Lower numbers mean more preferred. */ | |||
| 624 | const int type_ranks[_SESSION_TYPE_MAX] = { | |||
| 625 | [SESSION_UNSPECIFIED] = 0, | |||
| 626 | [SESSION_TTY] = -2, | |||
| 627 | [SESSION_X11] = -3, | |||
| 628 | [SESSION_WAYLAND] = -3, | |||
| 629 | [SESSION_MIR] = -3, | |||
| 630 | [SESSION_WEB] = -1, | |||
| 631 | }; | |||
| 632 | ||||
| 633 | /* Calculate the partial order relationship between s1 and s2, | |||
| 634 | * returning < 0 if s1 is preferred as the user’s ‘primary session’, | |||
| 635 | * 0 if s1 and s2 are equally preferred or incomparable, or > 0 if s2 | |||
| 636 | * is preferred. | |||
| 637 | * | |||
| 638 | * s1 or s2 may be NULL. */ | |||
| 639 | if (!s1 && !s2) | |||
| 640 | return 0; | |||
| 641 | ||||
| 642 | if ((s1 == NULL((void*)0)) != (s2 == NULL((void*)0))) | |||
| 643 | return (s1 == NULL((void*)0)) - (s2 == NULL((void*)0)); | |||
| 644 | ||||
| 645 | if (s1->stopping != s2->stopping) | |||
| 646 | return s1->stopping - s2->stopping; | |||
| 647 | ||||
| 648 | if ((s1->class != SESSION_USER) != (s2->class != SESSION_USER)) | |||
| 649 | return (s1->class != SESSION_USER) - (s2->class != SESSION_USER); | |||
| 650 | ||||
| 651 | if ((s1->type == _SESSION_TYPE_INVALID) != (s2->type == _SESSION_TYPE_INVALID)) | |||
| 652 | return (s1->type == _SESSION_TYPE_INVALID) - (s2->type == _SESSION_TYPE_INVALID); | |||
| 653 | ||||
| 654 | if (s1->type != s2->type) | |||
| 655 | return type_ranks[s1->type] - type_ranks[s2->type]; | |||
| 656 | ||||
| 657 | return 0; | |||
| 658 | } | |||
| 659 | ||||
| 660 | void user_elect_display(User *u) { | |||
| 661 | Session *s; | |||
| 662 | ||||
| 663 | assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("u"), "../src/login/logind-user.c", 663, __PRETTY_FUNCTION__); } while (0); | |||
| 664 | ||||
| 665 | /* This elects a primary session for each user, which we call | |||
| 666 | * the "display". We try to keep the assignment stable, but we | |||
| 667 | * "upgrade" to better choices. */ | |||
| 668 | log_debug("Electing new display for user %s", u->name)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 668, __func__, "Electing new display for user %s" , u->name) : -abs(_e); }); | |||
| 669 | ||||
| 670 | LIST_FOREACH(sessions_by_user, s, u->sessions)for ((s) = (u->sessions); (s); (s) = (s)->sessions_by_user_next ) { | |||
| 671 | if (!elect_display_filter(s)) { | |||
| 672 | log_debug("Ignoring session %s", s->id)({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 672, __func__, "Ignoring session %s" , s->id) : -abs(_e); }); | |||
| 673 | continue; | |||
| 674 | } | |||
| 675 | ||||
| 676 | if (elect_display_compare(s, u->display) < 0) { | |||
| 677 | log_debug("Choosing session %s in preference to %s", s->id, u->display ? u->display->id : "-")({ int _level = (((7))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 677, __func__, "Choosing session %s in preference to %s" , s->id, u->display ? u->display->id : "-") : -abs (_e); }); | |||
| 678 | u->display = s; | |||
| 679 | } | |||
| 680 | } | |||
| 681 | } | |||
| 682 | ||||
| 683 | static const char* const user_state_table[_USER_STATE_MAX] = { | |||
| 684 | [USER_OFFLINE] = "offline", | |||
| 685 | [USER_OPENING] = "opening", | |||
| 686 | [USER_LINGERING] = "lingering", | |||
| 687 | [USER_ONLINE] = "online", | |||
| 688 | [USER_ACTIVE] = "active", | |||
| 689 | [USER_CLOSING] = "closing" | |||
| 690 | }; | |||
| 691 | ||||
| 692 | DEFINE_STRING_TABLE_LOOKUP(user_state, UserState)const char *user_state_to_string(UserState i) { if (i < 0 || i >= (UserState) __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(user_state_table), typeof(&*(user_state_table))), sizeof(user_state_table)/sizeof((user_state_table)[0]), ((void )0)))) return ((void*)0); return user_state_table[i]; } UserState user_state_from_string(const char *s) { return (UserState) string_table_lookup (user_state_table, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p (typeof(user_state_table), typeof(&*(user_state_table))), sizeof(user_state_table)/sizeof((user_state_table)[0]), ((void )0))), s); }; | |||
| 693 | ||||
| 694 | int config_parse_tmpfs_size( | |||
| 695 | const char* unit, | |||
| 696 | const char *filename, | |||
| 697 | unsigned line, | |||
| 698 | const char *section, | |||
| 699 | unsigned section_line, | |||
| 700 | const char *lvalue, | |||
| 701 | int ltype, | |||
| 702 | const char *rvalue, | |||
| 703 | void *data, | |||
| 704 | void *userdata) { | |||
| 705 | ||||
| 706 | uint64_t *sz = data; | |||
| 707 | int r; | |||
| 708 | ||||
| 709 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/login/logind-user.c" , 709, __PRETTY_FUNCTION__); } while (0); | |||
| 710 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/login/logind-user.c", 710, __PRETTY_FUNCTION__); } while (0); | |||
| 711 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/login/logind-user.c", 711, __PRETTY_FUNCTION__); } while (0); | |||
| 712 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/login/logind-user.c", 712 , __PRETTY_FUNCTION__); } while (0); | |||
| 713 | ||||
| 714 | /* First, try to parse as percentage */ | |||
| 715 | r = parse_percent(rvalue); | |||
| 716 | if (r > 0 && r < 100) | |||
| 717 | *sz = physical_memory_scale(r, 100U); | |||
| 718 | else { | |||
| 719 | uint64_t k; | |||
| 720 | ||||
| 721 | /* If the passed argument was not a percentage, or out of range, parse as byte size */ | |||
| 722 | ||||
| 723 | r = parse_size(rvalue, 1024, &k); | |||
| 724 | if (r < 0 || k <= 0 || (uint64_t) (size_t) k != k) { | |||
| 725 | log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse size value, ignoring: %s", rvalue)({ int _level = (3), _e = (r); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/login/logind-user.c", 725, __func__ , "Failed to parse size value, ignoring: %s", rvalue) : -abs( _e); }); | |||
| 726 | return 0; | |||
| 727 | } | |||
| 728 | ||||
| 729 | *sz = PAGE_ALIGN((size_t) k)ALIGN_TO(((size_t) k), page_size()); | |||
| 730 | } | |||
| 731 | ||||
| 732 | return 0; | |||
| 733 | } | |||
| 734 | ||||
| 735 | int config_parse_compat_user_tasks_max( | |||
| 736 | const char *unit, | |||
| 737 | const char *filename, | |||
| 738 | unsigned line, | |||
| 739 | const char *section, | |||
| 740 | unsigned section_line, | |||
| 741 | const char *lvalue, | |||
| 742 | int ltype, | |||
| 743 | const char *rvalue, | |||
| 744 | void *data, | |||
| 745 | void *userdata) { | |||
| 746 | ||||
| 747 | assert(filename)do { if ((__builtin_expect(!!(!(filename)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("filename"), "../src/login/logind-user.c" , 747, __PRETTY_FUNCTION__); } while (0); | |||
| 748 | assert(lvalue)do { if ((__builtin_expect(!!(!(lvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("lvalue"), "../src/login/logind-user.c", 748, __PRETTY_FUNCTION__); } while (0); | |||
| 749 | assert(rvalue)do { if ((__builtin_expect(!!(!(rvalue)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("rvalue"), "../src/login/logind-user.c", 749, __PRETTY_FUNCTION__); } while (0); | |||
| 750 | assert(data)do { if ((__builtin_expect(!!(!(data)),0))) log_assert_failed_realm (LOG_REALM_SYSTEMD, ("data"), "../src/login/logind-user.c", 750 , __PRETTY_FUNCTION__); } while (0); | |||
| 751 | ||||
| 752 | log_syntax(unit, LOG_NOTICE, filename, line, 0,({ int _level = (5), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/login/logind-user.c", 754, __func__ , "Support for option %s= has been removed.", lvalue) : -abs( _e); }) | |||
| 753 | "Support for option %s= has been removed.",({ int _level = (5), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/login/logind-user.c", 754, __func__ , "Support for option %s= has been removed.", lvalue) : -abs( _e); }) | |||
| 754 | lvalue)({ int _level = (5), _e = (0); (log_get_max_level_realm(LOG_REALM_SYSTEMD ) >= ((_level) & 0x07)) ? log_syntax_internal(unit, _level , filename, line, _e, "../src/login/logind-user.c", 754, __func__ , "Support for option %s= has been removed.", lvalue) : -abs( _e); }); | |||
| 755 | log_info("Hint: try creating /etc/systemd/system/user-.slice/50-limits.conf with:\n"({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 758, __func__, "Hint: try creating /etc/systemd/system/user-.slice/50-limits.conf with:\n" " [Slice]\n" " TasksMax=%s", rvalue) : -abs(_e ); }) | |||
| 756 | " [Slice]\n"({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 758, __func__, "Hint: try creating /etc/systemd/system/user-.slice/50-limits.conf with:\n" " [Slice]\n" " TasksMax=%s", rvalue) : -abs(_e ); }) | |||
| 757 | " TasksMax=%s",({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 758, __func__, "Hint: try creating /etc/systemd/system/user-.slice/50-limits.conf with:\n" " [Slice]\n" " TasksMax=%s", rvalue) : -abs(_e ); }) | |||
| 758 | rvalue)({ int _level = (((6))), _e = ((0)), _realm = (LOG_REALM_SYSTEMD ); (log_get_max_level_realm(_realm) >= ((_level) & 0x07 )) ? log_internal_realm(((_realm) << 10 | (_level)), _e , "../src/login/logind-user.c", 758, __func__, "Hint: try creating /etc/systemd/system/user-.slice/50-limits.conf with:\n" " [Slice]\n" " TasksMax=%s", rvalue) : -abs(_e ); }); | |||
| 759 | return 0; | |||
| 760 | } |