static void test_linked_units(const char *root) { const char *p, *q; UnitFileState state; UnitFileChange *changes = NULL; unsigned n_changes = 0, i; /* * We'll test three cases here: * * a) a unit file in /opt, that we use "systemctl link" and * "systemctl enable" on to make it available to the system * * b) a unit file in /opt, that is statically linked into * /usr/lib/systemd/system, that "enable" should work on * correctly. * * c) a unit file in /opt, that is linked into * /etc/systemd/system, and where "enable" should result in * -ELOOP, since using information from /etc to generate * information in /etc should not be allowed. */ p = strjoina(root, "/opt/linked.service"); assert_se(write_string_file(p, "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); p = strjoina(root, "/opt/linked2.service"); assert_se(write_string_file(p, "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); p = strjoina(root, "/opt/linked3.service"); assert_se(write_string_file(p, "[Install]\n" "WantedBy=multi-user.target\n", WRITE_STRING_FILE_CREATE) >= 0); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked2.service", NULL) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked3.service", NULL) == -ENOENT); p = strjoina(root, "/usr/lib/systemd/system/linked2.service"); assert_se(symlink("/opt/linked2.service", p) >= 0); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked3.service"); assert_se(symlink("/opt/linked3.service", p) >= 0); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) == -ENOENT); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked2.service", &state) >= 0 && state == UNIT_FILE_DISABLED); assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked3.service", &state) >= 0 && state == UNIT_FILE_LINKED); /* First, let's link the unit into the search path */ assert_se(unit_file_link(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[0].source, "/opt/linked.service")); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_LINKED); /* Let's unlink it from the search path again */ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_UNLINK); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); assert_se(streq(changes[0].path, p)); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT); /* Now, let's not just link it, but also enable it */ assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("/opt/linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); for (i = 0 ; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[i].source, "/opt/linked.service")); if (p && streq(changes[i].path, p)) p = NULL; else if (q && streq(changes[i].path, q)) q = NULL; else assert_not_reached("wut?"); } assert(!p && !q); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", &state) >= 0 && state == UNIT_FILE_ENABLED); /* And let's unlink it again */ assert_se(unit_file_disable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked.service"); for (i = 0; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_UNLINK); if (p && streq(changes[i].path, p)) p = NULL; else if (q && streq(changes[i].path, q)) q = NULL; else assert_not_reached("wut?"); } assert(!p && !q); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_get_state(UNIT_FILE_SYSTEM, root, "linked.service", NULL) == -ENOENT); assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked2.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 2); p = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/multi-user.target.wants/linked2.service"); q = strjoina(root, SYSTEM_CONFIG_UNIT_PATH"/linked2.service"); for (i = 0 ; i < n_changes; i++) { assert_se(changes[i].type == UNIT_FILE_SYMLINK); assert_se(streq(changes[i].source, "/opt/linked2.service")); if (p && streq(changes[i].path, p)) p = NULL; else if (q && streq(changes[i].path, q)) q = NULL; else assert_not_reached("wut?"); } assert(!p && !q); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; assert_se(unit_file_enable(UNIT_FILE_SYSTEM, 0, root, STRV_MAKE("linked3.service"), &changes, &n_changes) >= 0); assert_se(n_changes == 1); assert_se(changes[0].type == UNIT_FILE_SYMLINK); assert_se(startswith(changes[0].path, root)); assert_se(endswith(changes[0].path, "linked3.service")); assert_se(streq(changes[0].source, "/opt/linked3.service")); unit_file_changes_free(changes, n_changes); changes = NULL; n_changes = 0; }
n_changes = 0; r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes); assert_se(r >= 0); dump_changes(changes, n_changes); unit_file_changes_free(changes, n_changes); r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state); assert_se(r < 0); log_error("link files2"); changes = NULL; n_changes = 0; r = unit_file_link(UNIT_FILE_SYSTEM, false, NULL, (char**) files2, false, &changes, &n_changes); assert_se(r >= 0); dump_changes(changes, n_changes); unit_file_changes_free(changes, n_changes); r = unit_file_get_state(UNIT_FILE_SYSTEM, NULL, basename(files2[0]), &state); assert_se(r >= 0); assert_se(state == UNIT_FILE_LINKED); log_error("disable files2"); changes = NULL; n_changes = 0; r = unit_file_disable(UNIT_FILE_SYSTEM, false, NULL, STRV_MAKE(basename(files2[0])), &changes, &n_changes); assert_se(r >= 0);