Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/stand/efi/libefi/efizfs.c
34860 views
1
/*-
2
* Copyright (c) 2008-2010 Rui Paulo
3
* Copyright (c) 2006 Marcel Moolenaar
4
* All rights reserved.
5
*
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
8
* are met:
9
*
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
*/
27
28
#include <sys/param.h>
29
#include <stand.h>
30
31
#ifdef EFI_ZFS_BOOT
32
#include <libzfs.h>
33
#endif
34
35
#include <efi.h>
36
#include <efilib.h>
37
38
#include "efizfs.h"
39
40
#ifdef EFI_ZFS_BOOT
41
static zfsinfo_list_t zfsinfo;
42
43
uint64_t pool_guid;
44
45
zfsinfo_list_t *
46
efizfs_get_zfsinfo_list(void)
47
{
48
return (&zfsinfo);
49
}
50
51
EFI_HANDLE
52
efizfs_get_handle_by_guid(uint64_t guid)
53
{
54
zfsinfo_t *zi;
55
56
STAILQ_FOREACH(zi, &zfsinfo, zi_link) {
57
if (zi->zi_pool_guid == guid) {
58
return (zi->zi_handle);
59
}
60
}
61
return (NULL);
62
}
63
64
bool
65
efizfs_get_guid_by_handle(EFI_HANDLE handle, uint64_t *guid)
66
{
67
zfsinfo_t *zi;
68
69
if (guid == NULL)
70
return (false);
71
STAILQ_FOREACH(zi, &zfsinfo, zi_link) {
72
if (zi->zi_handle == handle) {
73
*guid = zi->zi_pool_guid;
74
return (true);
75
}
76
}
77
return (false);
78
}
79
80
static void
81
insert_zfs(EFI_HANDLE handle, uint64_t guid)
82
{
83
zfsinfo_t *zi;
84
85
zi = malloc(sizeof(zfsinfo_t));
86
if (zi != NULL) {
87
zi->zi_handle = handle;
88
zi->zi_pool_guid = guid;
89
STAILQ_INSERT_TAIL(&zfsinfo, zi, zi_link);
90
}
91
}
92
93
void
94
efi_zfs_probe(void)
95
{
96
pdinfo_list_t *hdi;
97
pdinfo_t *hd, *pd = NULL;
98
char devname[SPECNAMELEN + 1];
99
uint64_t guid;
100
101
hdi = efiblk_get_pdinfo_list(&efipart_hddev);
102
STAILQ_INIT(&zfsinfo);
103
104
/*
105
* Find the handle for the boot device. The boot1 did find the
106
* device with loader binary, now we need to search for the
107
* same device and if it is part of the zfs pool, we record the
108
* pool GUID for currdev setup.
109
*/
110
STAILQ_FOREACH(hd, hdi, pd_link) {
111
STAILQ_FOREACH(pd, &hd->pd_part, pd_link) {
112
snprintf(devname, sizeof(devname), "%s%dp%d:",
113
efipart_hddev.dv_name, hd->pd_unit, pd->pd_unit);
114
guid = 0;
115
if (zfs_probe_dev(devname, &guid, false) == 0) {
116
insert_zfs(pd->pd_handle, guid);
117
if (pd->pd_handle == boot_img->DeviceHandle)
118
pool_guid = guid;
119
}
120
121
}
122
}
123
}
124
#endif
125
126