1 // SPDX-License-Identifier: CDDL-1.0
2 /*
3 * CDDL HEADER START
4 *
5 * The contents of this file are subject to the terms of the
6 * Common Development and Distribution License (the "License").
7 * You may not use this file except in compliance with the License.
8 *
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or https://opensource.org/licenses/CDDL-1.0.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
13 *
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
19 *
20 * CDDL HEADER END
21 */
22
23 /*
24 * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
25 * Copyright (c) 2013, 2018 by Delphix. All rights reserved.
26 * Copyright (c) 2016, 2017 Intel Corporation.
27 * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>.
28 */
29
30 /*
31 * Functions to convert between a list of vdevs and an nvlist representing the
32 * configuration. Each entry in the list can be one of:
33 *
34 * Device vdevs
35 * disk=(path=..., devid=...)
36 * file=(path=...)
37 *
38 * Group vdevs
39 * raidz[1|2]=(...)
40 * mirror=(...)
41 *
42 * Hot spares
43 *
44 * While the underlying implementation supports it, group vdevs cannot contain
45 * other group vdevs. All userland verification of devices is contained within
46 * this file. If successful, the nvlist returned can be passed directly to the
47 * kernel; we've done as much verification as possible in userland.
48 *
49 * Hot spares are a special case, and passed down as an array of disk vdevs, at
50 * the same level as the root of the vdev tree.
51 *
52 * The only function exported by this file is 'make_root_vdev'. The
53 * function performs several passes:
54 *
55 * 1. Construct the vdev specification. Performs syntax validation and
56 * makes sure each device is valid.
57 * 2. Check for devices in use. Using libdiskmgt, makes sure that no
58 * devices are also in use. Some can be overridden using the 'force'
59 * flag, others cannot.
60 * 3. Check for replication errors if the 'force' flag is not specified.
61 * validates that the replication level is consistent across the
62 * entire pool.
63 * 4. Call libzfs to label any whole disks with an EFI label.
64 */
65
66 #include <assert.h>
67 #include <errno.h>
68 #include <fcntl.h>
69 #include <libintl.h>
70 #include <libnvpair.h>
71 #include <libzutil.h>
72 #include <limits.h>
73 #include <sys/spa.h>
74 #include <stdio.h>
75 #include <string.h>
76 #include <unistd.h>
77 #include <paths.h>
78 #include <sys/stat.h>
79 #include <sys/disk.h>
80 #include <sys/mntent.h>
81 #include <libgeom.h>
82
83 #include "zpool_util.h"
84 #include <sys/zfs_context.h>
85
86 int
check_device(const char * name,boolean_t force,boolean_t isspare,boolean_t iswholedisk)87 check_device(const char *name, boolean_t force, boolean_t isspare,
88 boolean_t iswholedisk)
89 {
90 (void) iswholedisk;
91 char path[MAXPATHLEN];
92
93 if (strncmp(name, _PATH_DEV, sizeof (_PATH_DEV) - 1) != 0)
94 snprintf(path, sizeof (path), "%s%s", _PATH_DEV, name);
95 else
96 strlcpy(path, name, sizeof (path));
97
98 return (check_file(path, force, isspare));
99 }
100
101 boolean_t
check_sector_size_database(char * path,int * sector_size)102 check_sector_size_database(char *path, int *sector_size)
103 {
104 (void) path, (void) sector_size;
105 return (0);
106 }
107
108 void
after_zpool_upgrade(zpool_handle_t * zhp)109 after_zpool_upgrade(zpool_handle_t *zhp)
110 {
111 char bootfs[ZPOOL_MAXPROPLEN];
112
113 if (zpool_get_prop(zhp, ZPOOL_PROP_BOOTFS, bootfs,
114 sizeof (bootfs), NULL, B_FALSE) == 0 &&
115 strcmp(bootfs, "-") != 0) {
116 (void) printf(gettext("Pool '%s' has the bootfs "
117 "property set, you might need to update\nthe boot "
118 "code. See gptzfsboot(8) and loader.efi(8) for "
119 "details.\n"), zpool_get_name(zhp));
120 }
121 }
122
123 int
check_file(const char * file,boolean_t force,boolean_t isspare)124 check_file(const char *file, boolean_t force, boolean_t isspare)
125 {
126 return (check_file_generic(file, force, isspare));
127 }
128
129 int
zpool_power_current_state(zpool_handle_t * zhp,char * vdev)130 zpool_power_current_state(zpool_handle_t *zhp, char *vdev)
131 {
132
133 (void) zhp;
134 (void) vdev;
135 /* Enclosure slot power not supported on FreeBSD yet */
136 return (-1);
137 }
138
139 int
zpool_power(zpool_handle_t * zhp,char * vdev,boolean_t turn_on)140 zpool_power(zpool_handle_t *zhp, char *vdev, boolean_t turn_on)
141 {
142
143 (void) zhp;
144 (void) vdev;
145 (void) turn_on;
146 /* Enclosure slot power not supported on FreeBSD yet */
147 return (ENOTSUP);
148 }
149