Print this page
patch zone-auto-create-be


   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 2015 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 <strings.h>
  38 #include <errno.h>
  39 #include <sys/mnttab.h>
  40 #include <sys/types.h>
  41 #include <sys/stat.h>
  42 #include <fcntl.h>
  43 #include <unistd.h>
  44 #include <sys/efi_partition.h>
  45 
  46 #include <libbe.h>
  47 #include <libbe_priv.h>


1373  *              be_name - the name of the global zone BE that we need to
1374  *                       find the zones for.
1375  *              be_root_ds - the root dataset for be_name.
1376  * Return:
1377  *              BE_SUCCESS - Success
1378  *              be_errno_t - Failure
1379  *
1380  * Scope:
1381  *              Private
1382  */
1383 static int
1384 be_promote_zone_ds(char *be_name, char *be_root_ds)
1385 {
1386         char            *zone_ds = NULL;
1387         char            *temp_mntpt = NULL;
1388         char            origin[MAXPATHLEN];
1389         char            zoneroot_ds[MAXPATHLEN];
1390         zfs_handle_t    *zhp = NULL;
1391         zfs_handle_t    *z_zhp = NULL;
1392         zoneList_t      zone_list = NULL;
1393         zoneBrandList_t *brands = NULL;
1394         boolean_t       be_mounted = B_FALSE;
1395         int             zone_index = 0;
1396         int             err = BE_SUCCESS;
1397 
1398         /*
1399          * Get the supported zone brands so we can pass that
1400          * to z_get_nonglobal_zone_list_by_brand. Currently
1401          * only the ipkg and labeled brand zones are supported
1402          *
1403          */
1404         if ((brands = be_get_supported_brandlist()) == NULL) {
1405                 be_print_err(gettext("be_promote_zone_ds: no supported "
1406                     "brands\n"));
1407                 return (BE_SUCCESS);
1408         }
1409 
1410         if ((zhp = zfs_open(g_zfs, be_root_ds,
1411             ZFS_TYPE_FILESYSTEM)) == NULL) {
1412                 be_print_err(gettext("be_promote_zone_ds: Failed to open "
1413                     "dataset (%s): %s\n"), be_root_ds,
1414                     libzfs_error_description(g_zfs));
1415                 err = zfs_err_to_be_err(g_zfs);
1416                 z_free_brand_list(brands);
1417                 return (err);
1418         }
1419 
1420         if (!zfs_is_mounted(zhp, &temp_mntpt)) {
1421                 if ((err = _be_mount(be_name, &temp_mntpt,
1422                     BE_MOUNT_FLAG_NO_ZONES)) != BE_SUCCESS) {
1423                         be_print_err(gettext("be_promote_zone_ds: failed to "
1424                             "mount the BE for zones procesing.\n"));
1425                         ZFS_CLOSE(zhp);
1426                         z_free_brand_list(brands);
1427                         return (err);
1428                 }
1429                 be_mounted = B_TRUE;
1430         }
1431 
1432         /*
1433          * Set the zone root to the temp mount point for the BE we just mounted.
1434          */
1435         z_set_zone_root(temp_mntpt);
1436 
1437         /*
1438          * Get all the zones based on the brands we're looking for. If no zones
1439          * are found that we're interested in unmount the BE and move on.
1440          */
1441         if ((zone_list = z_get_nonglobal_zone_list_by_brand(brands)) == NULL) {
1442                 if (be_mounted)
1443                         (void) _be_unmount(be_name, 0);
1444                 ZFS_CLOSE(zhp);
1445                 z_free_brand_list(brands);
1446                 free(temp_mntpt);
1447                 return (BE_SUCCESS);
1448         }
1449         for (zone_index = 0; z_zlist_get_zonename(zone_list, zone_index)
1450             != NULL; zone_index++) {
1451                 char *zone_path = NULL;












1452 
1453                 /* Skip zones that aren't at least installed */
1454                 if (z_zlist_get_current_state(zone_list, zone_index) <
1455                     ZONE_STATE_INSTALLED)
1456                         continue;
1457 
1458                 if (((zone_path =
1459                     z_zlist_get_zonepath(zone_list, zone_index)) == NULL) ||
1460                     ((zone_ds = be_get_ds_from_dir(zone_path)) == NULL) ||
1461                     !be_zone_supported(zone_ds))
1462                         continue;
1463 
1464                 if (be_find_active_zone_root(zhp, zone_ds,
1465                     zoneroot_ds, sizeof (zoneroot_ds)) != 0) {
1466                         be_print_err(gettext("be_promote_zone_ds: "
1467                             "Zone does not have an active root "
1468                             "dataset, skipping this zone.\n"));
1469                         continue;
1470                 }
1471 


1488                 /*
1489                  * We don't need to close the zfs handle at this
1490                  * point because the callback funtion
1491                  * be_promote_ds_callback() will close it for us.
1492                  */
1493                 if (be_promote_ds_callback(z_zhp, NULL) != 0) {
1494                         be_print_err(gettext("be_promote_zone_ds: "
1495                             "failed to activate the "
1496                             "datasets for %s: %s\n"),
1497                             zoneroot_ds,
1498                             libzfs_error_description(g_zfs));
1499                         err = BE_ERR_PROMOTE;
1500                         goto done;
1501                 }
1502         }
1503 done:
1504         if (be_mounted)
1505                 (void) _be_unmount(be_name, 0);
1506         ZFS_CLOSE(zhp);
1507         free(temp_mntpt);
1508         z_free_brand_list(brands);
1509         z_free_zone_list(zone_list);
1510         return (err);
1511 }
1512 
1513 /*
1514  * Function:    be_promote_ds_callback
1515  * Description: This function is used to promote the datasets for the BE
1516  *              being activated as well as the datasets for the zones BE
1517  *              being activated.
1518  *
1519  * Parameters:
1520  *              zhp - the zfs handle for zone BE being activated.
1521  *              data - not used.
1522  * Return:
1523  *              0 - Success
1524  *              be_errno_t - Failure
1525  *
1526  * Scope:
1527  *              Private
1528  */




   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 2015 Nexenta Systems, Inc. All rights reserved.
  28  * Copyright 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
  29  */
  30 
  31 #include <assert.h>
  32 #include <libintl.h>
  33 #include <libnvpair.h>
  34 #include <libzfs.h>
  35 #include <stdio.h>
  36 #include <stdlib.h>
  37 #include <string.h>
  38 #include <strings.h>
  39 #include <errno.h>
  40 #include <sys/mnttab.h>
  41 #include <sys/types.h>
  42 #include <sys/stat.h>
  43 #include <fcntl.h>
  44 #include <unistd.h>
  45 #include <sys/efi_partition.h>
  46 
  47 #include <libbe.h>
  48 #include <libbe_priv.h>


1374  *              be_name - the name of the global zone BE that we need to
1375  *                       find the zones for.
1376  *              be_root_ds - the root dataset for be_name.
1377  * Return:
1378  *              BE_SUCCESS - Success
1379  *              be_errno_t - Failure
1380  *
1381  * Scope:
1382  *              Private
1383  */
1384 static int
1385 be_promote_zone_ds(char *be_name, char *be_root_ds)
1386 {
1387         char            *zone_ds = NULL;
1388         char            *temp_mntpt = NULL;
1389         char            origin[MAXPATHLEN];
1390         char            zoneroot_ds[MAXPATHLEN];
1391         zfs_handle_t    *zhp = NULL;
1392         zfs_handle_t    *z_zhp = NULL;
1393         zoneList_t      zone_list = NULL;

1394         boolean_t       be_mounted = B_FALSE;
1395         int             zone_index = 0;
1396         int             err = BE_SUCCESS;
1397 












1398         if ((zhp = zfs_open(g_zfs, be_root_ds,
1399             ZFS_TYPE_FILESYSTEM)) == NULL) {
1400                 be_print_err(gettext("be_promote_zone_ds: Failed to open "
1401                     "dataset (%s): %s\n"), be_root_ds,
1402                     libzfs_error_description(g_zfs));
1403                 err = zfs_err_to_be_err(g_zfs);

1404                 return (err);
1405         }
1406 
1407         if (!zfs_is_mounted(zhp, &temp_mntpt)) {
1408                 if ((err = _be_mount(be_name, &temp_mntpt,
1409                     BE_MOUNT_FLAG_NO_ZONES)) != BE_SUCCESS) {
1410                         be_print_err(gettext("be_promote_zone_ds: failed to "
1411                             "mount the BE for zones procesing.\n"));
1412                         ZFS_CLOSE(zhp);

1413                         return (err);
1414                 }
1415                 be_mounted = B_TRUE;
1416         }
1417 
1418         /*
1419          * Set the zone root to the temp mount point for the BE we just mounted.
1420          */
1421         z_set_zone_root(temp_mntpt);
1422 
1423         /*
1424          * If no zones are found, unmount the BE and move on.

1425          */
1426         if ((zone_list = z_get_nonglobal_branded_zone_list()) == NULL) {
1427                 if (be_mounted)
1428                         (void) _be_unmount(be_name, 0);
1429                 ZFS_CLOSE(zhp);

1430                 free(temp_mntpt);
1431                 return (BE_SUCCESS);
1432         }
1433         for (zone_index = 0; z_zlist_get_zonename(zone_list, zone_index)
1434             != NULL; zone_index++) {
1435                 char *zone_path = NULL;
1436                 boolean_t auto_create;
1437 
1438                 if (z_zlist_is_zone_auto_create_be(zone_list, zone_index,
1439                     &auto_create) != 0) {
1440                         be_print_err(gettext("be_promote_zone_ds: "
1441                             "Failed to get auto-create-be brand property\n"));
1442                         err = -1; // XXX
1443                         goto done;
1444                 }
1445 
1446                 if (!auto_create)
1447                         continue;
1448 
1449                 /* Skip zones that aren't at least installed */
1450                 if (z_zlist_get_current_state(zone_list, zone_index) <
1451                     ZONE_STATE_INSTALLED)
1452                         continue;
1453 
1454                 if (((zone_path =
1455                     z_zlist_get_zonepath(zone_list, zone_index)) == NULL) ||
1456                     ((zone_ds = be_get_ds_from_dir(zone_path)) == NULL) ||
1457                     !be_zone_supported(zone_ds))
1458                         continue;
1459 
1460                 if (be_find_active_zone_root(zhp, zone_ds,
1461                     zoneroot_ds, sizeof (zoneroot_ds)) != 0) {
1462                         be_print_err(gettext("be_promote_zone_ds: "
1463                             "Zone does not have an active root "
1464                             "dataset, skipping this zone.\n"));
1465                         continue;
1466                 }
1467 


1484                 /*
1485                  * We don't need to close the zfs handle at this
1486                  * point because the callback funtion
1487                  * be_promote_ds_callback() will close it for us.
1488                  */
1489                 if (be_promote_ds_callback(z_zhp, NULL) != 0) {
1490                         be_print_err(gettext("be_promote_zone_ds: "
1491                             "failed to activate the "
1492                             "datasets for %s: %s\n"),
1493                             zoneroot_ds,
1494                             libzfs_error_description(g_zfs));
1495                         err = BE_ERR_PROMOTE;
1496                         goto done;
1497                 }
1498         }
1499 done:
1500         if (be_mounted)
1501                 (void) _be_unmount(be_name, 0);
1502         ZFS_CLOSE(zhp);
1503         free(temp_mntpt);

1504         z_free_zone_list(zone_list);
1505         return (err);
1506 }
1507 
1508 /*
1509  * Function:    be_promote_ds_callback
1510  * Description: This function is used to promote the datasets for the BE
1511  *              being activated as well as the datasets for the zones BE
1512  *              being activated.
1513  *
1514  * Parameters:
1515  *              zhp - the zfs handle for zone BE being activated.
1516  *              data - not used.
1517  * Return:
1518  *              0 - Success
1519  *              be_errno_t - Failure
1520  *
1521  * Scope:
1522  *              Private
1523  */