Print this page
*** NO COMMENTS ***
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libbe/common/be_list.c
+++ new/usr/src/lib/libbe/common/be_list.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
↓ open down ↓ |
16 lines elided |
↑ open up ↑ |
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 */
25 25
26 26 /*
27 - * Copyright 2011 Nexenta Systems, Inc. All rights reserved.
27 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
28 28 */
29 29
30 30 #include <assert.h>
31 31 #include <libintl.h>
32 32 #include <libnvpair.h>
33 33 #include <libzfs.h>
34 34 #include <stdio.h>
35 35 #include <stdlib.h>
36 36 #include <string.h>
37 37 #include <strings.h>
38 38 #include <sys/types.h>
39 39 #include <sys/stat.h>
40 40 #include <unistd.h>
41 41 #include <errno.h>
42 42
43 43 #include <libbe.h>
44 44 #include <libbe_priv.h>
45 45
46 46 /*
47 47 * Callback data used for zfs_iter calls.
48 48 */
49 49 typedef struct list_callback_data {
50 50 char *zpool_name;
51 51 char *be_name;
52 52 be_node_list_t *be_nodes_head;
53 53 be_node_list_t *be_nodes;
54 54 char current_be[MAXPATHLEN];
55 55 } list_callback_data_t;
56 56
57 57 /*
58 58 * Private function prototypes
59 59 */
60 60 static int be_add_children_callback(zfs_handle_t *zhp, void *data);
61 61 static int be_get_list_callback(zpool_handle_t *, void *);
62 62 static int be_get_node_data(zfs_handle_t *, be_node_list_t *, char *,
63 63 const char *, char *, char *);
64 64 static int be_get_zone_node_data(be_node_list_t *, char *);
65 65 static int be_get_ds_data(zfs_handle_t *, char *, be_dataset_list_t *,
66 66 be_node_list_t *);
67 67 static int be_get_ss_data(zfs_handle_t *, char *, be_snapshot_list_t *,
68 68 be_node_list_t *);
69 69 static void be_sort_list(be_node_list_t **);
70 70 static int be_qsort_compare_BEs(const void *, const void *);
71 71 static int be_qsort_compare_snapshots(const void *x, const void *y);
72 72 static int be_qsort_compare_datasets(const void *x, const void *y);
73 73 static void *be_list_alloc(int *, size_t);
74 74
75 75 /*
76 76 * Private data.
77 77 */
78 78 static char be_container_ds[MAXPATHLEN];
79 79 static boolean_t zone_be = B_FALSE;
80 80
81 81 /* ******************************************************************** */
82 82 /* Public Functions */
83 83 /* ******************************************************************** */
84 84
85 85 /*
86 86 * Function: be_list
87 87 * Description: Calls _be_list which finds all the BEs on the system and
88 88 * returns the datasets and snapshots belonging to each BE.
89 89 * Also data, such as dataset and snapshot properties,
90 90 * for each BE and their snapshots and datasets is
91 91 * returned. The data returned is as described in the
92 92 * be_dataset_list_t, be_snapshot_list_t and be_node_list_t
93 93 * structures.
94 94 * Parameters:
95 95 * be_name - The name of the BE to look up.
96 96 * If NULL a list of all BEs will be returned.
97 97 * be_nodes - A reference pointer to the list of BEs. The list
98 98 * structure will be allocated by _be_list and must
99 99 * be freed by a call to be_free_list. If there are no
100 100 * BEs found on the system this reference will be
101 101 * set to NULL.
102 102 * Return:
103 103 * BE_SUCCESS - Success
104 104 * be_errno_t - Failure
105 105 * Scope:
106 106 * Public
107 107 */
108 108 int
109 109 be_list(char *be_name, be_node_list_t **be_nodes)
110 110 {
111 111 int ret = BE_SUCCESS;
112 112
113 113 /* Initialize libzfs handle */
114 114 if (!be_zfs_init())
115 115 return (BE_ERR_INIT);
116 116
117 117 /* Validate be_name if its not NULL */
118 118 if (be_name != NULL) {
119 119 if (!be_valid_be_name(be_name)) {
120 120 be_print_err(gettext("be_list: "
121 121 "invalid BE name %s\n"), be_name);
122 122 return (BE_ERR_INVAL);
123 123 }
124 124 }
125 125
126 126 ret = _be_list(be_name, be_nodes);
127 127
128 128 be_zfs_fini();
129 129
130 130 return (ret);
131 131 }
132 132
133 133 /* ******************************************************************** */
134 134 /* Semi-Private Functions */
135 135 /* ******************************************************************** */
136 136
137 137 /*
138 138 * Function: _be_list
139 139 * Description: This does the actual work described in be_list.
140 140 * Parameters:
141 141 * be_name - The name of the BE to look up.
142 142 * If NULL a list of all BEs will be returned.
143 143 * be_nodes - A reference pointer to the list of BEs. The list
144 144 * structure will be allocated here and must
145 145 * be freed by a call to be_free_list. If there are no
146 146 * BEs found on the system this reference will be
147 147 * set to NULL.
148 148 * Return:
149 149 * BE_SUCCESS - Success
150 150 * be_errno_t - Failure
151 151 * Scope:
152 152 * Semi-private (library wide use only)
153 153 */
154 154 int
155 155 _be_list(char *be_name, be_node_list_t **be_nodes)
156 156 {
157 157 list_callback_data_t cb = { 0 };
158 158 be_transaction_data_t bt = { 0 };
159 159 int ret = BE_SUCCESS;
160 160 zpool_handle_t *zphp;
161 161 char *rpool = NULL;
162 162 struct be_defaults be_defaults;
163 163
164 164 if (be_nodes == NULL)
165 165 return (BE_ERR_INVAL);
166 166
167 167 be_get_defaults(&be_defaults);
168 168
169 169 if (be_find_current_be(&bt) != BE_SUCCESS) {
170 170 /*
171 171 * We were unable to find a currently booted BE which
172 172 * probably means that we're not booted in a BE envoronment.
173 173 * None of the BE's will be marked as the active BE.
174 174 */
175 175 (void) strcpy(cb.current_be, "-");
176 176 } else {
177 177 (void) strncpy(cb.current_be, bt.obe_name,
178 178 sizeof (cb.current_be));
179 179 rpool = bt.obe_zpool;
180 180 }
↓ open down ↓ |
143 lines elided |
↑ open up ↑ |
181 181
182 182 /*
183 183 * If be_name is NULL we'll look for all BE's on the system.
184 184 * If not then we will only return data for the specified BE.
185 185 */
186 186 if (be_name != NULL)
187 187 cb.be_name = strdup(be_name);
188 188
189 189 if (be_defaults.be_deflt_rpool_container && rpool != NULL) {
190 190 if ((zphp = zpool_open(g_zfs, rpool)) == NULL) {
191 - be_print_err(gettext("be_get_node_data: failed to "
191 + be_print_err(gettext("be_list: failed to "
192 192 "open rpool (%s): %s\n"), rpool,
193 193 libzfs_error_description(g_zfs));
194 194 free(cb.be_name);
195 195 return (zfs_err_to_be_err(g_zfs));
196 196 }
197 197
198 198 ret = be_get_list_callback(zphp, &cb);
199 199 } else {
200 200 if ((zpool_iter(g_zfs, be_get_list_callback, &cb)) != 0) {
201 201 if (cb.be_nodes_head != NULL) {
202 202 be_free_list(cb.be_nodes_head);
203 203 cb.be_nodes_head = NULL;
204 204 cb.be_nodes = NULL;
205 205 }
206 206 ret = BE_ERR_BE_NOENT;
207 207 }
208 208 }
209 209
210 210 if (cb.be_nodes_head == NULL) {
211 211 if (be_name != NULL)
212 212 be_print_err(gettext("be_list: BE (%s) does not "
213 213 "exist\n"), be_name);
214 214 else
215 215 be_print_err(gettext("be_list: No BE's found\n"));
216 216 ret = BE_ERR_BE_NOENT;
217 217 }
218 218
219 219 *be_nodes = cb.be_nodes_head;
220 220
221 221 free(cb.be_name);
222 222
223 223 be_sort_list(be_nodes);
224 224
225 225 return (ret);
226 226 }
227 227
228 228 /*
229 229 * Function: be_free_list
230 230 * Description: Frees up all the data allocated for the list of BEs,
231 231 * datasets and snapshots returned by be_list.
232 232 * Parameters:
233 233 * be_node - be_nodes_t structure returned from call to be_list.
234 234 * Returns:
235 235 * none
236 236 * Scope:
237 237 * Semi-private (library wide use only)
238 238 */
239 239 void
240 240 be_free_list(be_node_list_t *be_nodes)
241 241 {
242 242 be_node_list_t *temp_node = NULL;
243 243 be_node_list_t *list = be_nodes;
244 244
245 245 while (list != NULL) {
246 246 be_dataset_list_t *datasets = list->be_node_datasets;
247 247 be_snapshot_list_t *snapshots = list->be_node_snapshots;
248 248
249 249 while (datasets != NULL) {
250 250 be_dataset_list_t *temp_ds = datasets;
251 251 datasets = datasets->be_next_dataset;
252 252 free(temp_ds->be_dataset_name);
253 253 free(temp_ds->be_ds_mntpt);
254 254 free(temp_ds->be_ds_plcy_type);
255 255 free(temp_ds);
256 256 }
257 257
258 258 while (snapshots != NULL) {
259 259 be_snapshot_list_t *temp_ss = snapshots;
260 260 snapshots = snapshots->be_next_snapshot;
261 261 free(temp_ss->be_snapshot_name);
262 262 free(temp_ss->be_snapshot_type);
263 263 free(temp_ss);
264 264 }
265 265
266 266 temp_node = list;
267 267 list = list->be_next_node;
268 268 free(temp_node->be_node_name);
269 269 free(temp_node->be_root_ds);
270 270 free(temp_node->be_rpool);
271 271 free(temp_node->be_mntpt);
272 272 free(temp_node->be_policy_type);
273 273 free(temp_node->be_uuid_str);
274 274 free(temp_node);
275 275 }
276 276 }
277 277
278 278 /*
279 279 * Function: be_get_zone_be_list
280 280 * Description: Finds all the BEs for this zone on the system.
281 281 * Parameters:
282 282 * zone_be_name - The name of the BE to look up.
283 283 * zone_be_container_ds - The dataset for the zone.
284 284 * zbe_nodes - A reference pointer to the list of BEs. The list
285 285 * structure will be allocated here and must
286 286 * be freed by a call to be_free_list. If there are no
287 287 * BEs found on the system this reference will be
288 288 * set to NULL.
289 289 * Return:
290 290 * BE_SUCCESS - Success
291 291 * be_errno_t - Failure
292 292 * Scope:
293 293 * Semi-private (library wide use only)
294 294 */
295 295 int
296 296 be_get_zone_be_list(
297 297 /* LINTED */
298 298 char *zone_be_name,
299 299 char *zone_be_container_ds,
300 300 be_node_list_t **zbe_nodes)
301 301 {
302 302 zfs_handle_t *zhp = NULL;
303 303 list_callback_data_t cb = { 0 };
304 304 int ret = BE_SUCCESS;
305 305
306 306 if (zbe_nodes == NULL)
307 307 return (BE_ERR_INVAL);
308 308
309 309 if (!zfs_dataset_exists(g_zfs, zone_be_container_ds,
310 310 ZFS_TYPE_FILESYSTEM)) {
311 311 return (BE_ERR_BE_NOENT);
312 312 }
313 313
314 314 zone_be = B_TRUE;
315 315
316 316 if ((zhp = zfs_open(g_zfs, zone_be_container_ds,
317 317 ZFS_TYPE_FILESYSTEM)) == NULL) {
318 318 be_print_err(gettext("be_get_zone_be_list: failed to open "
319 319 "the zone BE dataset %s: %s\n"), zone_be_container_ds,
320 320 libzfs_error_description(g_zfs));
321 321 ret = zfs_err_to_be_err(g_zfs);
322 322 goto cleanup;
323 323 }
324 324
325 325 (void) strcpy(be_container_ds, zone_be_container_ds);
326 326
327 327 if (cb.be_nodes_head == NULL) {
328 328 if ((cb.be_nodes_head = be_list_alloc(&ret,
329 329 sizeof (be_node_list_t))) == NULL) {
330 330 ZFS_CLOSE(zhp);
331 331 goto cleanup;
332 332 }
333 333 cb.be_nodes = cb.be_nodes_head;
334 334 }
335 335 if (ret == 0)
336 336 ret = zfs_iter_filesystems(zhp, be_add_children_callback, &cb);
337 337 ZFS_CLOSE(zhp);
338 338
339 339 *zbe_nodes = cb.be_nodes_head;
340 340
341 341 cleanup:
342 342 zone_be = B_FALSE;
343 343
344 344 return (ret);
345 345 }
346 346
347 347 /* ******************************************************************** */
348 348 /* Private Functions */
349 349 /* ******************************************************************** */
350 350
351 351 /*
352 352 * Function: be_get_list_callback
353 353 * Description: Callback function used by zfs_iter to look through all
354 354 * the pools on the system looking for BEs. If a BE name was
355 355 * specified only that BE's information will be collected and
356 356 * returned.
357 357 * Parameters:
358 358 * zlp - handle to the first zfs dataset. (provided by the
359 359 * zfs_iter_* call)
360 360 * data - pointer to the callback data and where we'll pass
361 361 * the BE information back.
362 362 * Returns:
363 363 * 0 - Success
364 364 * be_errno_t - Failure
365 365 * Scope:
366 366 * Private
367 367 */
368 368 static int
369 369 be_get_list_callback(zpool_handle_t *zlp, void *data)
370 370 {
371 371 list_callback_data_t *cb = (list_callback_data_t *)data;
372 372 char be_ds[MAXPATHLEN];
373 373 char *open_ds = NULL;
374 374 char *rpool = NULL;
375 375 zfs_handle_t *zhp = NULL;
376 376 int ret = 0;
377 377
378 378 cb->zpool_name = rpool = (char *)zpool_get_name(zlp);
379 379
380 380 /*
381 381 * Generate string for the BE container dataset
382 382 */
383 383 be_make_container_ds(rpool, be_container_ds,
384 384 sizeof (be_container_ds));
385 385
386 386 /*
387 387 * If a BE name was specified we use it's root dataset in place of
388 388 * the container dataset. This is because we only want to collect
389 389 * the information for the specified BE.
390 390 */
391 391 if (cb->be_name != NULL) {
392 392 if (!be_valid_be_name(cb->be_name))
393 393 return (BE_ERR_INVAL);
394 394 /*
395 395 * Generate string for the BE root dataset
396 396 */
397 397 be_make_root_ds(rpool, cb->be_name, be_ds, sizeof (be_ds));
398 398 open_ds = be_ds;
399 399 } else {
400 400 open_ds = be_container_ds;
401 401 }
402 402
403 403 /*
404 404 * Check if the dataset exists
405 405 */
406 406 if (!zfs_dataset_exists(g_zfs, open_ds,
407 407 ZFS_TYPE_FILESYSTEM)) {
408 408 /*
409 409 * The specified dataset does not exist in this pool or
410 410 * there are no valid BE's in this pool. Try the next zpool.
411 411 */
412 412 zpool_close(zlp);
413 413 return (0);
414 414 }
415 415
416 416 if ((zhp = zfs_open(g_zfs, open_ds, ZFS_TYPE_FILESYSTEM)) == NULL) {
417 417 be_print_err(gettext("be_get_list_callback: failed to open "
418 418 "the BE dataset %s: %s\n"), open_ds,
419 419 libzfs_error_description(g_zfs));
420 420 ret = zfs_err_to_be_err(g_zfs);
421 421 zpool_close(zlp);
422 422 return (ret);
423 423 }
424 424
425 425 /*
426 426 * If a BE name was specified we iterate through the datasets
427 427 * and snapshots for this BE only. Otherwise we will iterate
428 428 * through the next level of datasets to find all the BE's
429 429 * within the pool
430 430 */
431 431 if (cb->be_name != NULL) {
432 432 if (cb->be_nodes_head == NULL) {
433 433 if ((cb->be_nodes_head = be_list_alloc(&ret,
434 434 sizeof (be_node_list_t))) == NULL) {
435 435 ZFS_CLOSE(zhp);
436 436 zpool_close(zlp);
437 437 return (ret);
438 438 }
439 439 cb->be_nodes = cb->be_nodes_head;
440 440 }
441 441
442 442 if ((ret = be_get_node_data(zhp, cb->be_nodes, cb->be_name,
443 443 rpool, cb->current_be, be_ds)) != BE_SUCCESS) {
444 444 ZFS_CLOSE(zhp);
445 445 zpool_close(zlp);
446 446 return (ret);
447 447 }
448 448 ret = zfs_iter_snapshots(zhp, be_add_children_callback, cb);
449 449 }
450 450
451 451 if (ret == 0)
452 452 ret = zfs_iter_filesystems(zhp, be_add_children_callback, cb);
453 453 ZFS_CLOSE(zhp);
454 454
455 455 zpool_close(zlp);
456 456 return (ret);
457 457 }
458 458
459 459 /*
460 460 * Function: be_add_children_callback
461 461 * Description: Callback function used by zfs_iter to look through all
462 462 * the datasets and snapshots for each BE and add them to
463 463 * the lists of information to be passed back.
464 464 * Parameters:
465 465 * zhp - handle to the first zfs dataset. (provided by the
466 466 * zfs_iter_* call)
467 467 * data - pointer to the callback data and where we'll pass
468 468 * the BE information back.
469 469 * Returns:
470 470 * 0 - Success
471 471 * be_errno_t - Failure
472 472 * Scope:
473 473 * Private
474 474 */
475 475 static int
476 476 be_add_children_callback(zfs_handle_t *zhp, void *data)
477 477 {
478 478 list_callback_data_t *cb = (list_callback_data_t *)data;
479 479 char *str = NULL, *ds_path = NULL;
480 480 int ret = 0;
481 481 struct be_defaults be_defaults;
482 482
483 483 be_get_defaults(&be_defaults);
484 484
485 485 ds_path = str = strdup(zfs_get_name(zhp));
486 486
487 487 /*
488 488 * get past the end of the container dataset plus the trailing "/"
489 489 */
490 490 str = str + (strlen(be_container_ds) + 1);
491 491 if (be_defaults.be_deflt_rpool_container) {
492 492 /* just skip if invalid */
493 493 if (!be_valid_be_name(str))
494 494 return (BE_SUCCESS);
495 495 }
496 496
497 497 if (cb->be_nodes_head == NULL) {
498 498 if ((cb->be_nodes_head = be_list_alloc(&ret,
499 499 sizeof (be_node_list_t))) == NULL) {
500 500 ZFS_CLOSE(zhp);
501 501 return (ret);
502 502 }
503 503 cb->be_nodes = cb->be_nodes_head;
504 504 }
505 505
506 506 if (zfs_get_type(zhp) == ZFS_TYPE_SNAPSHOT && !zone_be) {
507 507 be_snapshot_list_t *snapshots = NULL;
508 508 if (cb->be_nodes->be_node_snapshots == NULL) {
509 509 if ((cb->be_nodes->be_node_snapshots =
510 510 be_list_alloc(&ret, sizeof (be_snapshot_list_t)))
511 511 == NULL || ret != BE_SUCCESS) {
512 512 ZFS_CLOSE(zhp);
513 513 return (ret);
514 514 }
515 515 cb->be_nodes->be_node_snapshots->be_next_snapshot =
516 516 NULL;
517 517 snapshots = cb->be_nodes->be_node_snapshots;
518 518 } else {
519 519 for (snapshots = cb->be_nodes->be_node_snapshots;
520 520 snapshots != NULL;
521 521 snapshots = snapshots->be_next_snapshot) {
522 522 if (snapshots->be_next_snapshot != NULL)
523 523 continue;
524 524 /*
525 525 * We're at the end of the list add the
526 526 * new snapshot.
527 527 */
528 528 if ((snapshots->be_next_snapshot =
529 529 be_list_alloc(&ret,
530 530 sizeof (be_snapshot_list_t))) == NULL ||
531 531 ret != BE_SUCCESS) {
532 532 ZFS_CLOSE(zhp);
533 533 return (ret);
534 534 }
535 535 snapshots = snapshots->be_next_snapshot;
536 536 snapshots->be_next_snapshot = NULL;
537 537 break;
538 538 }
539 539 }
540 540 if ((ret = be_get_ss_data(zhp, str, snapshots,
541 541 cb->be_nodes)) != BE_SUCCESS) {
542 542 ZFS_CLOSE(zhp);
543 543 return (ret);
544 544 }
545 545 } else if (strchr(str, '/') == NULL) {
546 546 if (cb->be_nodes->be_node_name != NULL) {
547 547 if ((cb->be_nodes->be_next_node =
548 548 be_list_alloc(&ret, sizeof (be_node_list_t))) ==
549 549 NULL || ret != BE_SUCCESS) {
550 550 ZFS_CLOSE(zhp);
551 551 return (ret);
552 552 }
553 553 cb->be_nodes = cb->be_nodes->be_next_node;
554 554 cb->be_nodes->be_next_node = NULL;
555 555 }
556 556
557 557 /*
558 558 * If this is a zone root dataset then we only need
559 559 * the name of the zone BE at this point. We grab that
560 560 * and return.
561 561 */
562 562 if (zone_be) {
563 563 ret = be_get_zone_node_data(cb->be_nodes, str);
564 564 ZFS_CLOSE(zhp);
565 565 return (ret);
566 566 }
567 567
568 568 if ((ret = be_get_node_data(zhp, cb->be_nodes, str,
569 569 cb->zpool_name, cb->current_be, ds_path)) != BE_SUCCESS) {
570 570 ZFS_CLOSE(zhp);
571 571 return (ret);
572 572 }
573 573 } else if (strchr(str, '/') != NULL && !zone_be) {
574 574 be_dataset_list_t *datasets = NULL;
575 575 if (cb->be_nodes->be_node_datasets == NULL) {
576 576 if ((cb->be_nodes->be_node_datasets =
577 577 be_list_alloc(&ret, sizeof (be_dataset_list_t)))
578 578 == NULL || ret != BE_SUCCESS) {
579 579 ZFS_CLOSE(zhp);
580 580 return (ret);
581 581 }
582 582 cb->be_nodes->be_node_datasets->be_next_dataset = NULL;
583 583 datasets = cb->be_nodes->be_node_datasets;
584 584 } else {
585 585 for (datasets = cb->be_nodes->be_node_datasets;
586 586 datasets != NULL;
587 587 datasets = datasets->be_next_dataset) {
588 588 if (datasets->be_next_dataset != NULL)
589 589 continue;
590 590 /*
591 591 * We're at the end of the list add
592 592 * the new dataset.
593 593 */
594 594 if ((datasets->be_next_dataset =
595 595 be_list_alloc(&ret,
596 596 sizeof (be_dataset_list_t)))
597 597 == NULL || ret != BE_SUCCESS) {
598 598 ZFS_CLOSE(zhp);
599 599 return (ret);
600 600 }
601 601 datasets = datasets->be_next_dataset;
602 602 datasets->be_next_dataset = NULL;
603 603 break;
604 604 }
605 605 }
606 606
607 607 if ((ret = be_get_ds_data(zhp, str,
608 608 datasets, cb->be_nodes)) != BE_SUCCESS) {
609 609 ZFS_CLOSE(zhp);
610 610 return (ret);
611 611 }
612 612 }
613 613 ret = zfs_iter_children(zhp, be_add_children_callback, cb);
614 614 if (ret != 0) {
615 615 be_print_err(gettext("be_add_children_callback: "
616 616 "encountered error: %s\n"),
617 617 libzfs_error_description(g_zfs));
618 618 ret = zfs_err_to_be_err(g_zfs);
619 619 }
620 620 ZFS_CLOSE(zhp);
621 621 return (ret);
622 622 }
623 623
624 624 /*
625 625 * Function: be_sort_list
626 626 * Description: Sort BE node list
627 627 * Parameters:
628 628 * pointer to address of list head
629 629 * Returns:
630 630 * nothing
631 631 * Side effect:
632 632 * node list sorted by name
633 633 * Scope:
634 634 * Private
635 635 */
636 636 static void
637 637 be_sort_list(be_node_list_t **pstart)
638 638 {
639 639 size_t ibe, nbe;
640 640 be_node_list_t *p = NULL;
641 641 be_node_list_t **ptrlist = NULL;
642 642
643 643 if (pstart == NULL)
644 644 return;
645 645 /* build array of linked list BE struct pointers */
646 646 for (p = *pstart, nbe = 0; p != NULL; nbe++, p = p->be_next_node) {
647 647 ptrlist = realloc(ptrlist,
648 648 sizeof (be_node_list_t *) * (nbe + 2));
649 649 ptrlist[nbe] = p;
650 650 }
651 651 if (nbe == 0)
652 652 return;
653 653 /* in-place list quicksort using qsort(3C) */
654 654 if (nbe > 1) /* no sort if less than 2 BEs */
655 655 qsort(ptrlist, nbe, sizeof (be_node_list_t *),
656 656 be_qsort_compare_BEs);
657 657
658 658 ptrlist[nbe] = NULL; /* add linked list terminator */
659 659 *pstart = ptrlist[0]; /* set new linked list header */
660 660 /* for each BE in list */
661 661 for (ibe = 0; ibe < nbe; ibe++) {
662 662 size_t k, ns; /* subordinate index, count */
663 663
664 664 /* rewrite list pointer chain, including terminator */
665 665 ptrlist[ibe]->be_next_node = ptrlist[ibe + 1];
666 666 /* sort subordinate snapshots */
667 667 if (ptrlist[ibe]->be_node_num_snapshots > 1) {
668 668 const size_t nmax = ptrlist[ibe]->be_node_num_snapshots;
669 669 be_snapshot_list_t ** const slist =
670 670 malloc(sizeof (be_snapshot_list_t *) * (nmax + 1));
671 671 be_snapshot_list_t *p;
672 672
673 673 if (slist == NULL)
674 674 continue;
675 675 /* build array of linked list snapshot struct ptrs */
676 676 for (ns = 0, p = ptrlist[ibe]->be_node_snapshots;
677 677 ns < nmax && p != NULL;
678 678 ns++, p = p->be_next_snapshot) {
679 679 slist[ns] = p;
680 680 }
681 681 if (ns < 2)
682 682 goto end_snapshot;
683 683 slist[ns] = NULL; /* add terminator */
684 684 /* in-place list quicksort using qsort(3C) */
685 685 qsort(slist, ns, sizeof (be_snapshot_list_t *),
686 686 be_qsort_compare_snapshots);
687 687 /* rewrite list pointer chain, including terminator */
688 688 ptrlist[ibe]->be_node_snapshots = slist[0];
689 689 for (k = 0; k < ns; k++)
690 690 slist[k]->be_next_snapshot = slist[k + 1];
691 691 end_snapshot:
692 692 free(slist);
693 693 }
694 694 /* sort subordinate datasets */
695 695 if (ptrlist[ibe]->be_node_num_datasets > 1) {
696 696 const size_t nmax = ptrlist[ibe]->be_node_num_datasets;
697 697 be_dataset_list_t ** const slist =
698 698 malloc(sizeof (be_dataset_list_t *) * (nmax + 1));
699 699 be_dataset_list_t *p;
700 700
701 701 if (slist == NULL)
702 702 continue;
703 703 /* build array of linked list dataset struct ptrs */
704 704 for (ns = 0, p = ptrlist[ibe]->be_node_datasets;
705 705 ns < nmax && p != NULL;
706 706 ns++, p = p->be_next_dataset) {
707 707 slist[ns] = p;
708 708 }
709 709 if (ns < 2) /* subordinate datasets < 2 - no sort */
710 710 goto end_dataset;
711 711 slist[ns] = NULL; /* add terminator */
712 712 /* in-place list quicksort using qsort(3C) */
713 713 qsort(slist, ns, sizeof (be_dataset_list_t *),
714 714 be_qsort_compare_datasets);
715 715 /* rewrite list pointer chain, including terminator */
716 716 ptrlist[ibe]->be_node_datasets = slist[0];
717 717 for (k = 0; k < ns; k++)
718 718 slist[k]->be_next_dataset = slist[k + 1];
719 719 end_dataset:
720 720 free(slist);
721 721 }
722 722 }
723 723 free:
724 724 free(ptrlist);
725 725 }
726 726
727 727 /*
728 728 * Function: be_qsort_compare_BEs
729 729 * Description: lexical compare of BE names for qsort(3C)
730 730 * Parameters:
731 731 * x,y - BEs with names to compare
732 732 * Returns:
733 733 * positive if y>x, negative if x>y, 0 if equal
734 734 * Scope:
735 735 * Private
736 736 */
737 737 static int
738 738 be_qsort_compare_BEs(const void *x, const void *y)
739 739 {
740 740 be_node_list_t *p = *(be_node_list_t **)x;
741 741 be_node_list_t *q = *(be_node_list_t **)y;
742 742
743 743 if (p == NULL || p->be_node_name == NULL)
744 744 return (1);
745 745 if (q == NULL || q->be_node_name == NULL)
746 746 return (-1);
747 747 return (strcmp(p->be_node_name, q->be_node_name));
748 748 }
749 749
750 750 /*
751 751 * Function: be_qsort_compare_snapshots
752 752 * Description: lexical compare of BE names for qsort(3C)
753 753 * Parameters:
754 754 * x,y - BE snapshots with names to compare
755 755 * Returns:
756 756 * positive if y>x, negative if x>y, 0 if equal
757 757 * Scope:
758 758 * Private
759 759 */
760 760 static int
761 761 be_qsort_compare_snapshots(const void *x, const void *y)
762 762 {
763 763 be_snapshot_list_t *p = *(be_snapshot_list_t **)x;
764 764 be_snapshot_list_t *q = *(be_snapshot_list_t **)y;
765 765
766 766 if (p == NULL || p->be_snapshot_name == NULL)
767 767 return (1);
768 768 if (q == NULL || q->be_snapshot_name == NULL)
769 769 return (-1);
770 770 return (strcmp(p->be_snapshot_name, q->be_snapshot_name));
771 771 }
772 772
773 773 /*
774 774 * Function: be_qsort_compare_datasets
775 775 * Description: lexical compare of dataset names for qsort(3C)
776 776 * Parameters:
777 777 * x,y - BE snapshots with names to compare
778 778 * Returns:
779 779 * positive if y>x, negative if x>y, 0 if equal
780 780 * Scope:
781 781 * Private
782 782 */
783 783 static int
784 784 be_qsort_compare_datasets(const void *x, const void *y)
785 785 {
786 786 be_dataset_list_t *p = *(be_dataset_list_t **)x;
787 787 be_dataset_list_t *q = *(be_dataset_list_t **)y;
788 788
789 789 if (p == NULL || p->be_dataset_name == NULL)
790 790 return (1);
791 791 if (q == NULL || q->be_dataset_name == NULL)
792 792 return (-1);
793 793 return (strcmp(p->be_dataset_name, q->be_dataset_name));
794 794 }
795 795
796 796 /*
797 797 * Function: be_get_node_data
798 798 * Description: Helper function used to collect all the information to fill
799 799 * in the be_node_list structure to be returned by be_list.
800 800 * Parameters:
801 801 * zhp - Handle to the root dataset for the BE whose information
802 802 * we're collecting.
803 803 * be_node - a pointer to the node structure we're filling in.
804 804 * be_name - The BE name of the node whose information we're
805 805 * collecting.
806 806 * current_be - the name of the currently active BE.
807 807 * be_ds - The dataset name for the BE.
808 808 *
809 809 * Returns:
810 810 * BE_SUCCESS - Success
811 811 * be_errno_t - Failure
812 812 * Scope:
813 813 * Private
814 814 */
815 815 static int
816 816 be_get_node_data(
↓ open down ↓ |
615 lines elided |
↑ open up ↑ |
817 817 zfs_handle_t *zhp,
818 818 be_node_list_t *be_node,
819 819 char *be_name,
820 820 const char *rpool,
821 821 char *current_be,
822 822 char *be_ds)
823 823 {
824 824 char prop_buf[MAXPATHLEN];
825 825 nvlist_t *userprops = NULL;
826 826 nvlist_t *propval = NULL;
827 + nvlist_t *zone_propval = NULL;
827 828 char *prop_str = NULL;
829 + char *zone_prop_str = NULL;
828 830 char *grub_default_bootfs = NULL;
829 831 zpool_handle_t *zphp = NULL;
830 832 int err = 0;
831 833
832 834 if (be_node == NULL || be_name == NULL || current_be == NULL ||
833 835 be_ds == NULL) {
834 836 be_print_err(gettext("be_get_node_data: invalid arguments, "
835 837 "can not be NULL\n"));
836 838 return (BE_ERR_INVAL);
837 839 }
838 840
839 841 errno = 0;
840 842
841 843 be_node->be_root_ds = strdup(be_ds);
842 844 if ((err = errno) != 0 || be_node->be_root_ds == NULL) {
843 845 be_print_err(gettext("be_get_node_data: failed to "
844 846 "copy root dataset name\n"));
845 847 return (errno_to_be_err(err));
846 848 }
847 849
848 850 be_node->be_node_name = strdup(be_name);
849 851 if ((err = errno) != 0 || be_node->be_node_name == NULL) {
850 852 be_print_err(gettext("be_get_node_data: failed to "
851 853 "copy BE name\n"));
852 854 return (errno_to_be_err(err));
853 855 }
854 856 if (strncmp(be_name, current_be, MAXPATHLEN) == 0)
855 857 be_node->be_active = B_TRUE;
856 858 else
857 859 be_node->be_active = B_FALSE;
↓ open down ↓ |
20 lines elided |
↑ open up ↑ |
858 860
859 861 be_node->be_rpool = strdup(rpool);
860 862 if (be_node->be_rpool == NULL || (err = errno) != 0) {
861 863 be_print_err(gettext("be_get_node_data: failed to "
862 864 "copy root pool name\n"));
863 865 return (errno_to_be_err(err));
864 866 }
865 867
866 868 be_node->be_space_used = zfs_prop_get_int(zhp, ZFS_PROP_USED);
867 869
868 - if ((zphp = zpool_open(g_zfs, rpool)) == NULL) {
869 - be_print_err(gettext("be_get_node_data: failed to open pool "
870 - "(%s): %s\n"), rpool, libzfs_error_description(g_zfs));
871 - return (zfs_err_to_be_err(g_zfs));
872 - }
870 + if (getzoneid() == GLOBAL_ZONEID) {
871 + if ((zphp = zpool_open(g_zfs, rpool)) == NULL) {
872 + be_print_err(gettext("be_get_node_data: failed to open "
873 + "pool (%s): %s\n"), rpool,
874 + libzfs_error_description(g_zfs));
875 + return (zfs_err_to_be_err(g_zfs));
876 + }
873 877
874 - (void) zpool_get_prop(zphp, ZPOOL_PROP_BOOTFS, prop_buf, ZFS_MAXPROPLEN,
875 - NULL);
876 - if (be_has_grub() &&
877 - (be_default_grub_bootfs(rpool, &grub_default_bootfs)
878 - == BE_SUCCESS) && grub_default_bootfs != NULL)
879 - if (strcmp(grub_default_bootfs, be_ds) == 0)
878 + (void) zpool_get_prop(zphp, ZPOOL_PROP_BOOTFS, prop_buf,
879 + ZFS_MAXPROPLEN, NULL);
880 + if (be_has_grub() && (be_default_grub_bootfs(rpool,
881 + &grub_default_bootfs) == BE_SUCCESS) &&
882 + grub_default_bootfs != NULL)
883 + if (strcmp(grub_default_bootfs, be_ds) == 0)
884 + be_node->be_active_on_boot = B_TRUE;
885 + else
886 + be_node->be_active_on_boot = B_FALSE;
887 + else if (prop_buf != NULL && strcmp(prop_buf, be_ds) == 0)
880 888 be_node->be_active_on_boot = B_TRUE;
881 889 else
882 890 be_node->be_active_on_boot = B_FALSE;
883 - else if (prop_buf != NULL && strcmp(prop_buf, be_ds) == 0)
884 - be_node->be_active_on_boot = B_TRUE;
885 - else
886 - be_node->be_active_on_boot = B_FALSE;
887 - free(grub_default_bootfs);
888 - zpool_close(zphp);
889 891
892 + be_node->be_global_active = B_TRUE;
893 +
894 + free(grub_default_bootfs);
895 + zpool_close(zphp);
896 + } else {
897 + if (be_zone_compare_uuids(be_node->be_root_ds))
898 + be_node->be_global_active = B_TRUE;
899 + else
900 + be_node->be_global_active = B_FALSE;
901 + }
902 +
890 903 /*
891 904 * If the dataset is mounted use the mount point
892 905 * returned from the zfs_is_mounted call. If the
893 906 * dataset is not mounted then pull the mount
894 907 * point information out of the zfs properties.
895 908 */
896 909 be_node->be_mounted = zfs_is_mounted(zhp,
897 910 &(be_node->be_mntpt));
898 911 if (!be_node->be_mounted) {
899 912 if (zfs_prop_get(zhp, ZFS_PROP_MOUNTPOINT, prop_buf,
900 913 ZFS_MAXPROPLEN, NULL, NULL, 0, B_FALSE) == 0)
901 914 be_node->be_mntpt = strdup(prop_buf);
902 915 else
↓ open down ↓ |
3 lines elided |
↑ open up ↑ |
903 916 return (zfs_err_to_be_err(g_zfs));
904 917 }
905 918
906 919 be_node->be_node_creation = (time_t)zfs_prop_get_int(zhp,
907 920 ZFS_PROP_CREATION);
908 921
909 922 /* Get all user properties used for libbe */
910 923 if ((userprops = zfs_get_user_props(zhp)) == NULL) {
911 924 be_node->be_policy_type = strdup(be_default_policy());
912 925 } else {
926 + if (getzoneid() != GLOBAL_ZONEID) {
927 + if (nvlist_lookup_nvlist(userprops,
928 + BE_ZONE_ACTIVE_PROPERTY, &zone_propval) != 0 ||
929 + zone_propval == NULL) {
930 + be_node->be_active_on_boot = B_FALSE;
931 + } else {
932 + verify(nvlist_lookup_string(zone_propval,
933 + ZPROP_VALUE, &zone_prop_str) == 0);
934 + if (strcmp(zone_prop_str, "on") == 0) {
935 + be_node->be_active_on_boot = B_TRUE;
936 + } else {
937 + be_node->be_active_on_boot = B_FALSE;
938 + }
939 + }
940 + }
941 +
913 942 if (nvlist_lookup_nvlist(userprops, BE_POLICY_PROPERTY,
914 943 &propval) != 0 || propval == NULL) {
915 944 be_node->be_policy_type =
916 945 strdup(be_default_policy());
917 946 } else {
918 947 verify(nvlist_lookup_string(propval, ZPROP_VALUE,
919 948 &prop_str) == 0);
920 949 if (prop_str == NULL || strcmp(prop_str, "-") == 0 ||
921 950 strcmp(prop_str, "") == 0)
922 951 be_node->be_policy_type =
923 952 strdup(be_default_policy());
924 953 else
925 954 be_node->be_policy_type = strdup(prop_str);
926 955 }
927 -
928 - if (nvlist_lookup_nvlist(userprops, BE_UUID_PROPERTY, &propval)
929 - == 0 && nvlist_lookup_string(propval, ZPROP_VALUE,
930 - &prop_str) == 0) {
931 - be_node->be_uuid_str = strdup(prop_str);
956 + if (getzoneid() != GLOBAL_ZONEID) {
957 + if (nvlist_lookup_nvlist(userprops,
958 + BE_ZONE_PARENTBE_PROPERTY, &propval) != 0 &&
959 + nvlist_lookup_string(propval, ZPROP_VALUE,
960 + &prop_str) == 0) {
961 + be_node->be_uuid_str = strdup(prop_str);
962 + }
963 + } else {
964 + if (nvlist_lookup_nvlist(userprops, BE_UUID_PROPERTY,
965 + &propval) == 0 && nvlist_lookup_string(propval,
966 + ZPROP_VALUE, &prop_str) == 0) {
967 + be_node->be_uuid_str = strdup(prop_str);
968 + }
932 969 }
933 970 }
934 971
935 972 /*
936 973 * Increment the dataset counter to include the root dataset
937 974 * of the BE.
938 975 */
939 976 be_node->be_node_num_datasets++;
940 977
941 978 return (BE_SUCCESS);
942 979 }
943 980
944 981 /*
945 982 * Function: be_get_ds_data
946 983 * Description: Helper function used by be_add_children_callback to collect
947 984 * the dataset related information that will be returned by
948 985 * be_list.
949 986 * Parameters:
950 987 * zhp - Handle to the zfs dataset whose information we're
951 988 * collecting.
952 989 * name - The name of the dataset we're processing.
953 990 * dataset - A pointer to the be_dataset_list structure
954 991 * we're filling in.
955 992 * node - The node structure that this dataset belongs to.
956 993 * Return:
957 994 * BE_SUCCESS - Success
958 995 * be_errno_t - Failure
959 996 * Scope:
960 997 * Private
961 998 */
962 999 static int
963 1000 be_get_ds_data(
964 1001 zfs_handle_t *zfshp,
965 1002 char *name,
966 1003 be_dataset_list_t *dataset,
967 1004 be_node_list_t *node)
968 1005 {
969 1006 char prop_buf[ZFS_MAXPROPLEN];
970 1007 nvlist_t *propval = NULL;
971 1008 nvlist_t *userprops = NULL;
972 1009 char *prop_str = NULL;
973 1010 int err = 0;
974 1011
975 1012 if (zfshp == NULL || name == NULL || dataset == NULL || node == NULL) {
976 1013 be_print_err(gettext("be_get_ds_data: invalid arguments, "
977 1014 "can not be NULL\n"));
978 1015 return (BE_ERR_INVAL);
979 1016 }
980 1017
981 1018 errno = 0;
982 1019
983 1020 dataset->be_dataset_name = strdup(name);
984 1021 if ((err = errno) != 0) {
985 1022 be_print_err(gettext("be_get_ds_data: failed to copy "
986 1023 "dataset name\n"));
987 1024 return (errno_to_be_err(err));
988 1025 }
989 1026
990 1027 dataset->be_ds_space_used = zfs_prop_get_int(zfshp, ZFS_PROP_USED);
991 1028
992 1029 /*
993 1030 * If the dataset is mounted use the mount point
994 1031 * returned from the zfs_is_mounted call. If the
995 1032 * dataset is not mounted then pull the mount
996 1033 * point information out of the zfs properties.
997 1034 */
998 1035 if (!(dataset->be_ds_mounted = zfs_is_mounted(zfshp,
999 1036 &(dataset->be_ds_mntpt)))) {
1000 1037 if (zfs_prop_get(zfshp, ZFS_PROP_MOUNTPOINT,
1001 1038 prop_buf, ZFS_MAXPROPLEN, NULL, NULL, 0,
1002 1039 B_FALSE) == 0)
1003 1040 dataset->be_ds_mntpt = strdup(prop_buf);
1004 1041 else
1005 1042 return (zfs_err_to_be_err(g_zfs));
1006 1043 }
1007 1044 dataset->be_ds_creation =
1008 1045 (time_t)zfs_prop_get_int(zfshp, ZFS_PROP_CREATION);
1009 1046
1010 1047 /*
1011 1048 * Get the user property used for the libbe
1012 1049 * cleaup policy
1013 1050 */
1014 1051 if ((userprops = zfs_get_user_props(zfshp)) == NULL) {
1015 1052 dataset->be_ds_plcy_type =
1016 1053 strdup(node->be_policy_type);
1017 1054 } else {
1018 1055 if (nvlist_lookup_nvlist(userprops,
1019 1056 BE_POLICY_PROPERTY, &propval) != 0 ||
1020 1057 propval == NULL) {
1021 1058 dataset->be_ds_plcy_type =
1022 1059 strdup(node->be_policy_type);
1023 1060 } else {
1024 1061 verify(nvlist_lookup_string(propval,
1025 1062 ZPROP_VALUE, &prop_str) == 0);
1026 1063 if (prop_str == NULL ||
1027 1064 strcmp(prop_str, "-") == 0 ||
1028 1065 strcmp(prop_str, "") == 0)
1029 1066 dataset->be_ds_plcy_type
1030 1067 = strdup(node->be_policy_type);
1031 1068 else
1032 1069 dataset->be_ds_plcy_type = strdup(prop_str);
1033 1070 }
1034 1071 }
1035 1072
1036 1073 node->be_node_num_datasets++;
1037 1074 return (BE_SUCCESS);
1038 1075 }
1039 1076
1040 1077 /*
1041 1078 * Function: be_get_ss_data
1042 1079 * Description: Helper function used by be_add_children_callback to collect
1043 1080 * the dataset related information that will be returned by
1044 1081 * be_list.
1045 1082 * Parameters:
1046 1083 * zhp - Handle to the zfs snapshot whose information we're
1047 1084 * collecting.
1048 1085 * name - The name of the snapshot we're processing.
1049 1086 * shapshot - A pointer to the be_snapshot_list structure
1050 1087 * we're filling in.
1051 1088 * node - The node structure that this snapshot belongs to.
1052 1089 * Returns:
1053 1090 * BE_SUCCESS - Success
1054 1091 * be_errno_t - Failure
1055 1092 * Scope:
1056 1093 * Private
1057 1094 */
1058 1095 static int
1059 1096 be_get_ss_data(
1060 1097 zfs_handle_t *zfshp,
1061 1098 char *name,
1062 1099 be_snapshot_list_t *snapshot,
1063 1100 be_node_list_t *node)
1064 1101 {
1065 1102 nvlist_t *propval = NULL;
1066 1103 nvlist_t *userprops = NULL;
1067 1104 char *prop_str = NULL;
1068 1105 int err = 0;
1069 1106
1070 1107 if (zfshp == NULL || name == NULL || snapshot == NULL || node == NULL) {
1071 1108 be_print_err(gettext("be_get_ss_data: invalid arguments, "
1072 1109 "can not be NULL\n"));
1073 1110 return (BE_ERR_INVAL);
1074 1111 }
1075 1112
1076 1113 errno = 0;
1077 1114
1078 1115 snapshot->be_snapshot_name = strdup(name);
1079 1116 if ((err = errno) != 0) {
1080 1117 be_print_err(gettext("be_get_ss_data: failed to copy name\n"));
1081 1118 return (errno_to_be_err(err));
1082 1119 }
1083 1120
1084 1121 snapshot->be_snapshot_creation = (time_t)zfs_prop_get_int(zfshp,
1085 1122 ZFS_PROP_CREATION);
1086 1123
1087 1124 /*
1088 1125 * Try to get this snapshot's cleanup policy from its
1089 1126 * user properties first. If not there, use default
1090 1127 * cleanup policy.
1091 1128 */
1092 1129 if ((userprops = zfs_get_user_props(zfshp)) != NULL &&
1093 1130 nvlist_lookup_nvlist(userprops, BE_POLICY_PROPERTY,
1094 1131 &propval) == 0 && nvlist_lookup_string(propval,
1095 1132 ZPROP_VALUE, &prop_str) == 0) {
1096 1133 snapshot->be_snapshot_type =
1097 1134 strdup(prop_str);
1098 1135 } else {
1099 1136 snapshot->be_snapshot_type =
1100 1137 strdup(be_default_policy());
1101 1138 }
1102 1139
1103 1140 snapshot->be_snapshot_space_used = zfs_prop_get_int(zfshp,
1104 1141 ZFS_PROP_USED);
1105 1142
1106 1143 node->be_node_num_snapshots++;
1107 1144 return (BE_SUCCESS);
1108 1145 }
1109 1146
1110 1147 /*
1111 1148 * Function: be_list_alloc
1112 1149 * Description: Helper function used to allocate memory for the various
1113 1150 * sructures that make up a BE node.
1114 1151 * Parameters:
1115 1152 * err - Used to return any errors encountered.
1116 1153 * BE_SUCCESS - Success
1117 1154 * BE_ERR_NOMEM - Allocation failure
1118 1155 * size - The size of memory to allocate.
1119 1156 * Returns:
1120 1157 * Success - A pointer to the allocated memory
1121 1158 * Failure - NULL
1122 1159 * Scope:
1123 1160 * Private
1124 1161 */
1125 1162 static void*
1126 1163 be_list_alloc(int *err, size_t size)
1127 1164 {
1128 1165 void *bep = NULL;
1129 1166
1130 1167 bep = calloc(1, size);
1131 1168 if (bep == NULL) {
1132 1169 be_print_err(gettext("be_list_alloc: memory "
1133 1170 "allocation failed\n"));
1134 1171 *err = BE_ERR_NOMEM;
1135 1172 }
1136 1173 *err = BE_SUCCESS;
1137 1174 return (bep);
1138 1175 }
1139 1176
1140 1177 /*
1141 1178 * Function: be_get_zone_node_data
1142 1179 * Description: Helper function used to collect all the information to
1143 1180 * fill in the be_node_list structure to be returned by
1144 1181 * be_get_zone_list.
1145 1182 * Parameters:
1146 1183 * be_node - a pointer to the node structure we're filling in.
1147 1184 * be_name - The BE name of the node whose information we're
1148 1185 * Returns:
1149 1186 * BE_SUCCESS - Success
1150 1187 * be_errno_t - Failure
1151 1188 * Scope:
1152 1189 * Private
1153 1190 *
1154 1191 * NOTE: This function currently only collects the zone BE name but when
1155 1192 * support for beadm/libbe in a zone is provided it will need to fill
1156 1193 * in the rest of the information needed for a zone BE.
1157 1194 */
1158 1195 static int
1159 1196 be_get_zone_node_data(be_node_list_t *be_node, char *be_name)
1160 1197 {
1161 1198 if ((be_node->be_node_name = strdup(be_name)) != NULL)
1162 1199 return (BE_SUCCESS);
1163 1200 return (BE_ERR_NOMEM);
1164 1201 }
↓ open down ↓ |
223 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX