Esempio n. 1
0
int boot_info_query(struct boot_info *info) {
        char str[64];
        char buf[64];
        char *loader_active = NULL;

        info->fw_secure_boot = is_efi_secure_boot();
        info->fw_secure_boot_setup_mode = is_efi_secure_boot_setup_mode();

        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &info->loader);

        get_boot_entries(info);
        if (info->fw_entries_count > 0) {
                get_boot_order(info);
                qsort(info->fw_entries, info->fw_entries_count, sizeof(struct boot_info_entry), entry_cmp);
                find_active_entry(info);
        }

        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareType", &info->fw_type);
        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareInfo", &info->fw_info);
        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderImageIdentifier", &info->loader_image_path);
        tilt_slashes(info->loader_image_path);
        efi_loader_get_device_part_uuid(&info->loader_part_uuid);

        boot_loader_read_entries(info);
        efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderEntrySelected", &loader_active);
        if (loader_active) {
                boot_loader_find_active_entry(info, loader_active);
                free(loader_active);
        }

        snprintf(str, sizeof(str), "LoaderEntryOptions-%s", sd_id128_to_string(info->machine_id, buf));
        efi_get_variable_string(EFI_VENDOR_LOADER, str, &info->loader_options_added);

        return 0;
}
static int find_gpt_root(struct udev_device *dev, blkid_probe pr, bool test) {

#if defined(GPT_ROOT_NATIVE) && defined(ENABLE_EFI)

    _cleanup_free_ char *root_id = NULL;
    bool found_esp = false;
    blkid_partlist pl;
    int i, nvals, r;

    assert(pr);

    /* Iterate through the partitions on this disk, and see if the
     * EFI ESP we booted from is on it. If so, find the first root
     * disk, and add a property indicating its partition UUID. */

    errno = 0;
    pl = blkid_probe_get_partitions(pr);
    if (!pl)
        return errno ? -errno : -ENOMEM;

    nvals = blkid_partlist_numof_partitions(pl);
    for (i = 0; i < nvals; i++) {
        blkid_partition pp;
        const char *stype, *sid;
        sd_id128_t type;

        pp = blkid_partlist_get_partition(pl, i);
        if (!pp)
            continue;

        sid = blkid_partition_get_uuid(pp);
        if (!sid)
            continue;

        stype = blkid_partition_get_type_string(pp);
        if (!stype)
            continue;

        if (sd_id128_from_string(stype, &type) < 0)
            continue;

        if (sd_id128_equal(type, GPT_ESP)) {
            sd_id128_t id, esp;

            /* We found an ESP, let's see if it matches
             * the ESP we booted from. */

            if (sd_id128_from_string(sid, &id) < 0)
                continue;

            r = efi_loader_get_device_part_uuid(&esp);
            if (r < 0)
                return r;

            if (sd_id128_equal(id, esp))
                found_esp = true;

        } else if (sd_id128_equal(type, GPT_ROOT_NATIVE)) {

            /* We found a suitable root partition, let's
             * remember the first one. */

            if (!root_id) {
                root_id = strdup(sid);
                if (!root_id)
                    return -ENOMEM;
            }
        }
    }

    /* We found the ESP on this disk, and also found a root
     * partition, nice! Let's export its UUID */
    if (found_esp && root_id)
        udev_builtin_add_property(dev, test, "ID_PART_GPT_AUTO_ROOT_UUID", root_id);
#endif

    return 0;
}
Esempio n. 3
0
static int bootctl_main(int argc, char*argv[]) {
        enum action {
                ACTION_STATUS,
                ACTION_INSTALL,
                ACTION_UPDATE,
                ACTION_REMOVE
        } arg_action = ACTION_STATUS;
        static const struct {
                const char* verb;
                enum action action;
        } verbs[] = {
                { "status",  ACTION_STATUS },
                { "install", ACTION_INSTALL },
                { "update",  ACTION_UPDATE },
                { "remove",  ACTION_REMOVE },
        };

        sd_id128_t uuid = {};
        uint32_t part = 0;
        uint64_t pstart = 0, psize = 0;
        int r, q;

        if (argv[optind]) {
                unsigned i;

                for (i = 0; i < ELEMENTSOF(verbs); i++) {
                        if (!streq(argv[optind], verbs[i].verb))
                                continue;
                        arg_action = verbs[i].action;
                        break;
                }
                if (i >= ELEMENTSOF(verbs)) {
                        log_error("Unknown operation \"%s\"", argv[optind]);
                        return -EINVAL;
                }
        }

        if (geteuid() != 0)
                return log_error_errno(EPERM, "Need to be root.");

        r = verify_esp(arg_path, &part, &pstart, &psize, &uuid);
        if (r == -ENODEV && !arg_path)
                log_notice("You might want to use --path= to indicate the path to your ESP, in case it is not mounted on /boot.");
        if (r < 0)
                return r;

        switch (arg_action) {
        case ACTION_STATUS: {
                _cleanup_free_ char *fw_type = NULL;
                _cleanup_free_ char *fw_info = NULL;
                _cleanup_free_ char *loader = NULL;
                _cleanup_free_ char *loader_path = NULL;
                sd_id128_t loader_part_uuid = {};

                if (is_efi_boot()) {
                        read_loader_efi_var("LoaderFirmwareType", &fw_type);
                        read_loader_efi_var("LoaderFirmwareInfo", &fw_info);
                        read_loader_efi_var("LoaderInfo", &loader);
                        read_loader_efi_var("LoaderImageIdentifier", &loader_path);
                        if (loader_path)
                                efi_tilt_backslashes(loader_path);
                        r = efi_loader_get_device_part_uuid(&loader_part_uuid);
                        if (r < 0 && r == -ENOENT)
                                log_warning_errno(r, "Failed to read EFI variable LoaderDevicePartUUID: %m");

                        printf("System:\n");
                        printf("     Firmware: %s (%s)\n", strna(fw_type), strna(fw_info));

                        r = is_efi_secure_boot();
                        if (r < 0)
                                log_warning_errno(r, "Failed to query secure boot status: %m");
                        else
                                printf("  Secure Boot: %s\n", r ? "enabled" : "disabled");

                        r = is_efi_secure_boot_setup_mode();
                        if (r < 0)
                                log_warning_errno(r, "Failed to query secure boot mode: %m");
                        else
                                printf("   Setup Mode: %s\n", r ? "setup" : "user");
                        printf("\n");

                        printf("Loader:\n");
                        printf("      Product: %s\n", strna(loader));
                        if (!sd_id128_equal(loader_part_uuid, SD_ID128_NULL))
                                printf("    Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
                                       SD_ID128_FORMAT_VAL(loader_part_uuid));
                        else
                                printf("    Partition: n/a\n");
                        printf("         File: %s%s\n", special_glyph(TREE_RIGHT), strna(loader_path));
                        printf("\n");
                } else
                        printf("System:\n    Not booted with EFI\n");

                r = status_binaries(arg_path, uuid);
                if (r < 0)
                        return r;

                if (arg_touch_variables)
                        r = status_variables();
                break;
        }

        case ACTION_INSTALL:
        case ACTION_UPDATE:
                umask(0002);

                r = install_binaries(arg_path, arg_action == ACTION_INSTALL);
                if (r < 0)
                        return r;

                if (arg_action == ACTION_INSTALL) {
                        r = install_loader_config(arg_path);
                        if (r < 0)
                                return r;
                }

                if (arg_touch_variables)
                        r = install_variables(arg_path,
                                              part, pstart, psize, uuid,
                                              "/EFI/systemd/systemd-boot" EFI_MACHINE_TYPE_NAME ".efi",
                                              arg_action == ACTION_INSTALL);
                break;

        case ACTION_REMOVE:
                r = remove_binaries(arg_path);

                if (arg_touch_variables) {
                        q = remove_variables(uuid, "/EFI/systemd/systemd-boot" EFI_MACHINE_TYPE_NAME ".efi", true);
                        if (q < 0 && r == 0)
                                r = q;
                }
                break;
        }

        return r;
}
Esempio n. 4
0
static int add_boot(const char *what) {
        _cleanup_blkid_free_probe_ blkid_probe b = NULL;
        const char *fstype = NULL, *uuid = NULL;
        sd_id128_t id, type_id;
        int r;

        assert(what);

        if (!is_efi_boot()) {
                log_debug("Not an EFI boot, ignoring /boot.");
                return 0;
        }

        if (in_initrd()) {
                log_debug("In initrd, ignoring /boot.");
                return 0;
        }

        if (detect_container() > 0) {
                log_debug("In a container, ignoring /boot.");
                return 0;
        }

        /* We create an .automount which is not overridden by the .mount from the fstab generator. */
        if (fstab_is_mount_point("/boot")) {
                log_debug("/boot specified in fstab, ignoring.");
                return 0;
        }

        if (path_is_busy("/boot")) {
                log_debug("/boot already populated, ignoring.");
                return 0;
        }

        r = efi_loader_get_device_part_uuid(&id);
        if (r == -ENOENT) {
                log_debug("EFI loader partition unknown.");
                return 0;
        }

        if (r < 0) {
                log_error_errno(r, "Failed to read ESP partition UUID: %m");
                return r;
        }

        errno = 0;
        b = blkid_new_probe_from_filename(what);
        if (!b) {
                if (errno == 0)
                        return log_oom();
                return log_error_errno(errno, "Failed to allocate prober: %m");
        }

        blkid_probe_enable_partitions(b, 1);
        blkid_probe_set_partitions_flags(b, BLKID_PARTS_ENTRY_DETAILS);

        errno = 0;
        r = blkid_do_safeprobe(b);
        if (r == -2 || r == 1) /* no result or uncertain */
                return 0;
        else if (r != 0)
                return log_error_errno(errno ?: EIO, "Failed to probe %s: %m", what);

        (void) blkid_probe_lookup_value(b, "TYPE", &fstype, NULL);
        if (!streq(fstype, "vfat")) {
                log_debug("Partition for /boot is not a FAT filesystem, ignoring.");
                return 0;
        }

        r = blkid_probe_lookup_value(b, "PART_ENTRY_UUID", &uuid, NULL);
        if (r != 0) {
                log_debug_errno(r, "Partition for /boot does not have a UUID, ignoring. %m");
                return 0;
        }

        if (sd_id128_from_string(uuid, &type_id) < 0) {
                log_debug("Partition for /boot does not have a valid UUID, ignoring.");
                return 0;
        }

        if (!sd_id128_equal(type_id, id)) {
                log_debug("Partition for /boot does not appear to be the partition we are booted from.");
                return 0;
        }

        r = add_automount("boot",
                       what,
                       "/boot",
                       "vfat",
                       true,
                       "umask=0077",
                       "EFI System Partition Automount",
                       120 * USEC_PER_SEC);

        return r;
}
Esempio n. 5
0
static int bootctl_main(int argc, char*argv[]) {
        enum action {
                ACTION_STATUS,
                ACTION_INSTALL,
                ACTION_UPDATE,
                ACTION_REMOVE
        } arg_action = ACTION_STATUS;
        static const struct {
                const char* verb;
                enum action action;
        } verbs[] = {
                { "status",  ACTION_STATUS },
                { "install", ACTION_INSTALL },
                { "update",  ACTION_UPDATE },
                { "remove",  ACTION_REMOVE },
        };

        sd_id128_t uuid = {};
        uint32_t part = 0;
        uint64_t pstart = 0;
        uint64_t psize = 0;
        unsigned int i;
        int q;
        int r;

        if (argv[optind]) {
                for (i = 0; i < ELEMENTSOF(verbs); i++) {
                        if (!streq(argv[optind], verbs[i].verb))
                                continue;
                        arg_action = verbs[i].action;
                        break;
                }
                if (i >= ELEMENTSOF(verbs)) {
                        fprintf(stderr, "Unknown operation %s\n", argv[optind]);
                        r = -EINVAL;
                        goto finish;
                }
        }

        if (!arg_path)
                arg_path = "/boot";

        if (geteuid() != 0) {
                fprintf(stderr, "Need to be root.\n");
                r = -EPERM;
                goto finish;
        }

        r = verify_esp(arg_path, &part, &pstart, &psize, &uuid);
        if (r == -ENODEV && !arg_path)
                fprintf(stderr, "You might want to use --path= to indicate the path to your ESP, in case it is not mounted to /boot.\n");
        if (r < 0)
                goto finish;

        switch (arg_action) {
        case ACTION_STATUS: {
                _cleanup_free_ char *fw_type = NULL;
                _cleanup_free_ char *fw_info = NULL;
                _cleanup_free_ char *loader = NULL;
                _cleanup_free_ char *loader_path = NULL;
                sd_id128_t loader_part_uuid = {};

                efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareType", &fw_type);
                efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderFirmwareInfo", &fw_info);
                efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderInfo", &loader);
                if (efi_get_variable_string(EFI_VENDOR_LOADER, "LoaderImageIdentifier", &loader_path) > 0)
                        efi_tilt_backslashes(loader_path);
                efi_loader_get_device_part_uuid(&loader_part_uuid);

                printf("System:\n");
                printf("     Firmware: %s (%s)\n", fw_type, strna(fw_info));
                printf("  Secure Boot: %s\n", is_efi_secure_boot() ? "enabled" : "disabled");
                printf("   Setup Mode: %s\n", is_efi_secure_boot_setup_mode() ? "setup" : "user");
                printf("\n");

                printf("Loader:\n");
                printf("      Product: %s\n", strna(loader));
                if (!sd_id128_equal(loader_part_uuid, SD_ID128_NULL))
                        printf("    Partition: /dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",
                               SD_ID128_FORMAT_VAL(loader_part_uuid));
                else
                        printf("    Partition: n/a\n");
                printf("         File: %s%s\n", draw_special_char(DRAW_TREE_RIGHT), strna(loader_path));
                printf("\n");

                r = status_binaries(arg_path, uuid);
                if (r < 0)
                        goto finish;

                if (arg_touch_variables)
                        r = status_variables();
                break;
        }

        case ACTION_INSTALL:
        case ACTION_UPDATE:
                umask(0002);

                r = install_binaries(arg_path, arg_action == ACTION_INSTALL);
                if (r < 0)
                        goto finish;

                if (arg_action == ACTION_INSTALL)
                        install_loader_config(arg_path);

                if (arg_touch_variables)
                        r = install_variables(arg_path,
                                              part, pstart, psize, uuid,
                                              "/EFI/systemd/systemd-boot" EFI_MACHINE_TYPE_NAME ".efi",
                                              arg_action == ACTION_INSTALL);
                break;

        case ACTION_REMOVE:
                r = remove_binaries(arg_path);

                if (arg_touch_variables) {
                        q = remove_variables(uuid, "/EFI/systemd/systemd-boot" EFI_MACHINE_TYPE_NAME ".efi", true);
                        if (q < 0 && r == 0)
                                r = q;
                }
                break;
        }

finish:
        return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}
int main(int argc, char *argv[]) {
    _cleanup_free_ char *what = NULL;
    _cleanup_fclose_ FILE *f = NULL;
    int r = EXIT_SUCCESS;
    sd_id128_t id;
    char *name;

    if (argc > 1 && argc != 4) {
        log_error("This program takes three or no arguments.");
        return EXIT_FAILURE;
    }

    if (argc > 1)
        arg_dest = argv[3];

    log_set_target(LOG_TARGET_SAFE);
    log_parse_environment();
    log_open();

    umask(0022);

    if (in_initrd()) {
        log_debug("In initrd, exiting.");
        return EXIT_SUCCESS;
    }

    if (detect_container(NULL) > 0) {
        log_debug("In a container, exiting.");
        return EXIT_SUCCESS;
    }

    if (!is_efi_boot()) {
        log_debug("Not an EFI boot, exiting.");
        return EXIT_SUCCESS;
    }

    if (path_is_mount_point("/boot", true) <= 0 &&
            dir_is_empty("/boot") <= 0) {
        log_debug("/boot already populated, exiting.");
        return EXIT_SUCCESS;
    }

    r = efi_loader_get_device_part_uuid(&id);
    if (r == -ENOENT) {
        log_debug("EFI loader partition unknown, exiting.");
        return EXIT_SUCCESS;
    } else if (r < 0) {
        log_error_errno(r, "Failed to read ESP partition UUID: %m");
        return EXIT_FAILURE;
    }

    name = strjoina(arg_dest, "/boot.mount");
    f = fopen(name, "wxe");
    if (!f) {
        log_error_errno(errno, "Failed to create mount unit file %s: %m", name);
        return EXIT_FAILURE;
    }

    r = asprintf(&what,
                 "/dev/disk/by-partuuid/%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
                 SD_ID128_FORMAT_VAL(id));
    if (r < 0) {
        log_oom();
        return EXIT_FAILURE;
    }

    fprintf(f,
            "# Automatially generated by systemd-efi-boot-generator\n\n"
            "[Unit]\n"
            "Description=EFI System Partition\n"
            "Documentation=man:systemd-efi-boot-generator(8)\n");

    r = generator_write_fsck_deps(f, arg_dest, what, "/boot", "vfat");
    if (r < 0)
        return EXIT_FAILURE;

    fprintf(f,
            "\n"
            "[Mount]\n"
            "What=%s\n"
            "Where=/boot\n"
            "Type=vfat\n"
            "Options=umask=0077,noauto\n",
            what);

    fflush(f);
    if (ferror(f)) {
        log_error_errno(errno, "Failed to write mount unit file: %m");
        return EXIT_FAILURE;
    }

    name = strjoina(arg_dest, "/boot.automount");
    fclose(f);
    f = fopen(name, "wxe");
    if (!f) {
        log_error_errno(errno, "Failed to create automount unit file %s: %m", name);
        return EXIT_FAILURE;
    }

    fputs("# Automatially generated by systemd-efi-boot-generator\n\n"
          "[Unit]\n"
          "Description=EFI System Partition Automount\n\n"
          "[Automount]\n"
          "Where=/boot\n", f);

    fflush(f);
    if (ferror(f)) {
        log_error_errno(errno, "Failed to write automount unit file: %m");
        return EXIT_FAILURE;
    }

    name = strjoina(arg_dest, "/" SPECIAL_LOCAL_FS_TARGET ".wants/boot.automount");
    mkdir_parents(name, 0755);

    if (symlink("../boot.automount", name) < 0) {
        log_error_errno(errno, "Failed to create symlink %s: %m", name);
        return EXIT_FAILURE;
    }

    return EXIT_SUCCESS;
}