6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 #include <assert.h>
27 #include <libintl.h>
28 #include <libnvpair.h>
29 #include <libzfs.h>
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <sys/mnttab.h>
35 #include <sys/types.h>
36 #include <sys/stat.h>
37 #include <unistd.h>
38
39 #include <libbe.h>
40 #include <libbe_priv.h>
41
42 char *mnttab = MNTTAB;
43
44 /*
45 * Private function prototypes
114 /* ******************************************************************** */
115
116 /*
117 * Function: _be_activate
118 * Description: This does the actual work described in be_activate.
119 * Parameters:
120 * be_name - pointer to the name of BE to activate.
121 *
122 * Return:
123 * BE_SUCCESS - Success
124 * be_errnot_t - Failure
125 * Scope:
126 * Public
127 */
128 int
129 _be_activate(char *be_name)
130 {
131 be_transaction_data_t cb = { 0 };
132 zfs_handle_t *zhp = NULL;
133 char root_ds[MAXPATHLEN];
134 char *cur_vers = NULL, *new_vers = NULL;
135 be_node_list_t *be_nodes = NULL;
136 uuid_t uu = {0};
137 int entry, ret = BE_SUCCESS;
138 int zret = 0;
139
140 /*
141 * TODO: The BE needs to be validated to make sure that it is actually
142 * a bootable BE.
143 */
144
145 if (be_name == NULL)
146 return (BE_ERR_INVAL);
147
148 /* Set obe_name to be_name in the cb structure */
149 cb.obe_name = be_name;
150
151 /* find which zpool the be is in */
152 if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &cb)) == 0) {
153 be_print_err(gettext("be_activate: failed to "
207 if (be_has_grub()) {
208 if ((ret = be_change_grub_default(cb.obe_name,
209 cb.obe_zpool)) != BE_SUCCESS) {
210 be_print_err(gettext("be_activate: failed to "
211 "change the default entry in menu.lst\n"));
212 goto done;
213 }
214 }
215 }
216
217 if ((ret = _be_list(cb.obe_name, &be_nodes)) != BE_SUCCESS) {
218 return (ret);
219 }
220
221 if ((ret = set_canmount(be_nodes, "noauto")) != BE_SUCCESS) {
222 be_print_err(gettext("be_activate: failed to set "
223 "canmount dataset property\n"));
224 goto done;
225 }
226
227 if ((ret = set_bootfs(be_nodes->be_rpool, root_ds)) != BE_SUCCESS) {
228 be_print_err(gettext("be_activate: failed to set "
229 "bootfs pool property for %s\n"), root_ds);
230 goto done;
231 }
232
233 if ((zhp = zfs_open(g_zfs, root_ds, ZFS_TYPE_FILESYSTEM)) != NULL) {
234 /*
235 * We don't need to close the zfs handle at this
236 * point because The callback funtion
237 * be_promote_ds_callback() will close it for us.
238 */
239 if (be_promote_ds_callback(zhp, NULL) != 0) {
240 be_print_err(gettext("be_activate: "
241 "failed to activate the "
242 "datasets for %s: %s\n"),
243 root_ds,
244 libzfs_error_description(g_zfs));
245 ret = BE_ERR_PROMOTE;
246 goto done;
247 }
248 } else {
249 be_print_err(gettext("be_activate:: failed to open "
250 "dataset (%s): %s\n"), root_ds,
251 libzfs_error_description(g_zfs));
252 ret = zfs_err_to_be_err(g_zfs);
253 goto done;
254 }
255
256 if (getzoneid() == GLOBAL_ZONEID &&
257 be_get_uuid(cb.obe_root_ds, &uu) == BE_SUCCESS &&
258 (ret = be_promote_zone_ds(cb.obe_name, cb.obe_root_ds))
259 != BE_SUCCESS) {
260 be_print_err(gettext("be_activate: failed to promote "
261 "the active zonepath datasets for zones in BE %s\n"),
262 cb.obe_name);
263 }
264
265 done:
266 be_free_list(be_nodes);
267 return (ret);
268 }
269
270 /*
271 * Function: be_activate_current_be
272 * Description: Set the currently "active" BE to be "active on boot"
273 * Paramters:
274 * none
275 * Returns:
276 * BE_SUCCESS - Success
277 * be_errnot_t - Failure
278 * Scope:
279 * Semi-private (library wide use only)
280 */
281 int
282 be_activate_current_be(void)
283 {
284 int ret = BE_SUCCESS;
|
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
28 */
29
30 #include <assert.h>
31 #include <libintl.h>
32 #include <libnvpair.h>
33 #include <libzfs.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 #include <errno.h>
38 #include <sys/mnttab.h>
39 #include <sys/types.h>
40 #include <sys/stat.h>
41 #include <unistd.h>
42
43 #include <libbe.h>
44 #include <libbe_priv.h>
45
46 char *mnttab = MNTTAB;
47
48 /*
49 * Private function prototypes
118 /* ******************************************************************** */
119
120 /*
121 * Function: _be_activate
122 * Description: This does the actual work described in be_activate.
123 * Parameters:
124 * be_name - pointer to the name of BE to activate.
125 *
126 * Return:
127 * BE_SUCCESS - Success
128 * be_errnot_t - Failure
129 * Scope:
130 * Public
131 */
132 int
133 _be_activate(char *be_name)
134 {
135 be_transaction_data_t cb = { 0 };
136 zfs_handle_t *zhp = NULL;
137 char root_ds[MAXPATHLEN];
138 char active_ds[MAXPATHLEN];
139 char *cur_vers = NULL, *new_vers = NULL;
140 be_node_list_t *be_nodes = NULL;
141 uuid_t uu = {0};
142 int entry, ret = BE_SUCCESS;
143 int zret = 0;
144
145 /*
146 * TODO: The BE needs to be validated to make sure that it is actually
147 * a bootable BE.
148 */
149
150 if (be_name == NULL)
151 return (BE_ERR_INVAL);
152
153 /* Set obe_name to be_name in the cb structure */
154 cb.obe_name = be_name;
155
156 /* find which zpool the be is in */
157 if ((zret = zpool_iter(g_zfs, be_find_zpool_callback, &cb)) == 0) {
158 be_print_err(gettext("be_activate: failed to "
212 if (be_has_grub()) {
213 if ((ret = be_change_grub_default(cb.obe_name,
214 cb.obe_zpool)) != BE_SUCCESS) {
215 be_print_err(gettext("be_activate: failed to "
216 "change the default entry in menu.lst\n"));
217 goto done;
218 }
219 }
220 }
221
222 if ((ret = _be_list(cb.obe_name, &be_nodes)) != BE_SUCCESS) {
223 return (ret);
224 }
225
226 if ((ret = set_canmount(be_nodes, "noauto")) != BE_SUCCESS) {
227 be_print_err(gettext("be_activate: failed to set "
228 "canmount dataset property\n"));
229 goto done;
230 }
231
232 if (getzoneid() == GLOBAL_ZONEID) {
233 if ((ret = set_bootfs(be_nodes->be_rpool,
234 root_ds)) != BE_SUCCESS) {
235 be_print_err(gettext("be_activate: failed to set "
236 "bootfs pool property for %s\n"), root_ds);
237 goto done;
238 }
239 }
240
241 if ((zhp = zfs_open(g_zfs, root_ds, ZFS_TYPE_FILESYSTEM)) != NULL) {
242 /*
243 * We don't need to close the zfs handle at this
244 * point because The callback funtion
245 * be_promote_ds_callback() will close it for us.
246 */
247 if (be_promote_ds_callback(zhp, NULL) != 0) {
248 be_print_err(gettext("be_activate: "
249 "failed to activate the "
250 "datasets for %s: %s\n"),
251 root_ds,
252 libzfs_error_description(g_zfs));
253 ret = BE_ERR_PROMOTE;
254 goto done;
255 }
256 } else {
257 be_print_err(gettext("be_activate: failed to open "
258 "dataset (%s): %s\n"), root_ds,
259 libzfs_error_description(g_zfs));
260 ret = zfs_err_to_be_err(g_zfs);
261 goto done;
262 }
263
264 if (getzoneid() == GLOBAL_ZONEID &&
265 be_get_uuid(cb.obe_root_ds, &uu) == BE_SUCCESS &&
266 (ret = be_promote_zone_ds(cb.obe_name, cb.obe_root_ds))
267 != BE_SUCCESS) {
268 be_print_err(gettext("be_activate: failed to promote "
269 "the active zonepath datasets for zones in BE %s\n"),
270 cb.obe_name);
271 }
272
273 if (getzoneid() != GLOBAL_ZONEID) {
274 if (!be_zone_compare_uuids(root_ds)) {
275 be_print_err(gettext("be_activate: activating zone "
276 "root dataset from non-active global BE is not "
277 "supported\n"));
278 ret = BE_ERR_NOTSUP;
279 goto done;
280 }
281 if ((zhp = zfs_open(g_zfs, root_ds,
282 ZFS_TYPE_FILESYSTEM)) == NULL) {
283 be_print_err(gettext("be_activate: failed to open "
284 "dataset (%s): %s\n"), root_ds,
285 libzfs_error_description(g_zfs));
286 ret = zfs_err_to_be_err(g_zfs);
287 goto done;
288 }
289 /* Find current active zone root dataset */
290 if ((ret = be_find_active_zone_root(zhp, cb.obe_zpool,
291 active_ds, sizeof (active_ds))) != BE_SUCCESS) {
292 be_print_err(gettext("be_activate: failed to find "
293 "active zone root dataset\n"));
294 ZFS_CLOSE(zhp);
295 goto done;
296 }
297 /* Do nothing if requested BE is already active */
298 if (strcmp(root_ds, active_ds) == 0) {
299 ret = BE_SUCCESS;
300 ZFS_CLOSE(zhp);
301 goto done;
302 }
303
304 /* Set active property for BE */
305 if (zfs_prop_set(zhp, BE_ZONE_ACTIVE_PROPERTY, "on") != 0) {
306 be_print_err(gettext("be_activate: failed to set "
307 "active property (%s): %s\n"), root_ds,
308 libzfs_error_description(g_zfs));
309 ret = zfs_err_to_be_err(g_zfs);
310 ZFS_CLOSE(zhp);
311 goto done;
312 }
313 ZFS_CLOSE(zhp);
314
315 /* Unset active property for old active root dataset */
316 if ((zhp = zfs_open(g_zfs, active_ds,
317 ZFS_TYPE_FILESYSTEM)) == NULL) {
318 be_print_err(gettext("be_activate: failed to open "
319 "dataset (%s): %s\n"), active_ds,
320 libzfs_error_description(g_zfs));
321 ret = zfs_err_to_be_err(g_zfs);
322 goto done;
323 }
324 if (zfs_prop_set(zhp, BE_ZONE_ACTIVE_PROPERTY, "off") != 0) {
325 be_print_err(gettext("be_activate: failed to unset "
326 "active property (%s): %s\n"), active_ds,
327 libzfs_error_description(g_zfs));
328 ret = zfs_err_to_be_err(g_zfs);
329 ZFS_CLOSE(zhp);
330 goto done;
331 }
332 ZFS_CLOSE(zhp);
333 }
334 done:
335 be_free_list(be_nodes);
336 return (ret);
337 }
338
339 /*
340 * Function: be_activate_current_be
341 * Description: Set the currently "active" BE to be "active on boot"
342 * Paramters:
343 * none
344 * Returns:
345 * BE_SUCCESS - Success
346 * be_errnot_t - Failure
347 * Scope:
348 * Semi-private (library wide use only)
349 */
350 int
351 be_activate_current_be(void)
352 {
353 int ret = BE_SUCCESS;
|