Print this page
patch tsoome-feedback


 335                         /* Create file system if it doesn't already exist */
 336                         if (zfs_dataset_exists(g_zfs, child_fs,
 337                             ZFS_TYPE_FILESYSTEM)) {
 338                                 continue;
 339                         }
 340                         if (zfs_create(g_zfs, child_fs, ZFS_TYPE_FILESYSTEM,
 341                             props) != 0) {
 342                                 be_print_err(gettext("be_init: failed to "
 343                                     "create BE's shared dataset (%s): %s\n"),
 344                                     child_fs, libzfs_error_description(g_zfs));
 345                                 ret = zfs_err_to_be_err(g_zfs);
 346                                 nvlist_free(props);
 347                                 goto done;
 348                         }
 349                 }
 350 
 351                 nvlist_free(props);
 352         }
 353 
 354 done:
 355         if (bt.nbe_zfs_props != NULL)
 356                 nvlist_free(bt.nbe_zfs_props);
 357 
 358         be_zfs_fini();
 359 
 360         return (ret);
 361 }
 362 
 363 /*
 364  * Function:    be_destroy
 365  * Description: Destroy a BE and all of its children datasets, snapshots and
 366  *              zones that belong to the parent BE.
 367  * Parameters:
 368  *              be_attrs - pointer to nvlist_t of attributes being passed in.
 369  *                      The following attributes are used by this function:
 370  *
 371  *                      BE_ATTR_ORIG_BE_NAME            *required
 372  *                      BE_ATTR_DESTROY_FLAGS           *optional
 373  * Return:
 374  *              BE_SUCCESS - Success
 375  *              be_errno_t - Failure


1150                         ret = zfs_err_to_be_err(g_zfs);
1151                         goto done;
1152                 }
1153 
1154                 /*
1155                  * Return the auto generated name to the caller
1156                  */
1157                 if (bt.nbe_name) {
1158                         if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_NAME,
1159                             bt.nbe_name) != 0) {
1160                                 be_print_err(gettext("be_copy: failed to "
1161                                     "add snap name to be_attrs\n"));
1162                         }
1163                 }
1164         }
1165 
1166 done:
1167         ZFS_CLOSE(zhp);
1168         be_free_fs_list(&fld);
1169 
1170         if (bt.nbe_zfs_props != NULL)
1171                 nvlist_free(bt.nbe_zfs_props);
1172 
1173         free(bt.obe_altroot);
1174         free(new_mp);
1175 
1176         /*
1177          * If a failure occurred and we already created the datasets for
1178          * the new boot environment, destroy them.
1179          */
1180         if (ret != BE_SUCCESS && be_created) {
1181                 be_destroy_data_t       cdd = { 0 };
1182 
1183                 cdd.force_unmount = B_TRUE;
1184 
1185                 be_print_err(gettext("be_copy: "
1186                     "destroying partially created boot environment\n"));
1187 
1188                 if (getzoneid() == GLOBAL_ZONEID && be_get_uuid(bt.nbe_root_ds,
1189                     &cdd.gz_be_uuid) == 0)
1190                         (void) be_destroy_zones(bt.nbe_name, bt.nbe_root_ds,


2073                 bt.nbe_root_ds = new_zoneroot_ds;
2074 
2075                 if (nvlist_alloc(&bt.nbe_zfs_props, NV_UNIQUE_NAME, 0) != 0) {
2076                         be_print_err(gettext("be_copy_zones: "
2077                             "internal error: out of memory\n"));
2078                         ret = BE_ERR_NOMEM;
2079                         goto done;
2080                 }
2081 
2082                 /*
2083                  * The call to be_clone_fs_callback always closes the
2084                  * zfs_handle so there's no need to close z_zhp.
2085                  */
2086                 if ((iret = be_clone_fs_callback(z_zhp, &bt)) != 0) {
2087                         z_zhp = NULL;
2088                         if (iret != BE_ERR_BE_EXISTS) {
2089                                 be_print_err(gettext("be_copy_zones: "
2090                                     "failed to create zone BE clone for new "
2091                                     "zone BE %s\n"), new_zone_be_name);
2092                                 ret = iret;
2093                                 if (bt.nbe_zfs_props != NULL)
2094                                         nvlist_free(bt.nbe_zfs_props);
2095                                 goto done;
2096                         }
2097                         /*
2098                          * We failed to create the new zone BE because a zone
2099                          * BE with the auto-name we generated above has since
2100                          * come into existence. Regenerate a new auto-name
2101                          * and retry.
2102                          */
2103                         for (num_retries = 1;
2104                             num_retries < BE_AUTO_NAME_MAX_TRY;
2105                             num_retries++) {
2106 
2107                                 /* Sleep 1 before retrying */
2108                                 (void) sleep(1);
2109 
2110                                 /* Generate new auto zone BE name */
2111                                 free(new_zone_be_name);
2112                                 if ((new_zone_be_name = be_auto_zone_be_name(
2113                                     zone_container_ds,
2114                                     zone_be_name)) == NULL) {
2115                                         be_print_err(gettext("be_copy_zones: "
2116                                             "failed to generate auto name "
2117                                             "for zone BE.\n"));
2118                                         ret = BE_ERR_AUTONAME;
2119                                         if (bt.nbe_zfs_props != NULL)
2120                                                 nvlist_free(bt.nbe_zfs_props);
2121                                         goto done;
2122                                 }
2123 
2124                                 (void) snprintf(new_zoneroot_ds,
2125                                     sizeof (new_zoneroot_ds),
2126                                     "%s/%s", zone_container_ds,
2127                                     new_zone_be_name);
2128                                 bt.nbe_name = new_zone_be_name;
2129                                 bt.nbe_root_ds = new_zoneroot_ds;
2130 
2131                                 /*
2132                                  * Get handle to original zone BE's root
2133                                  * dataset.
2134                                  */
2135                                 if ((z_zhp = zfs_open(g_zfs, zoneroot_ds,
2136                                     ZFS_TYPE_FILESYSTEM)) == NULL) {
2137                                         be_print_err(gettext("be_copy_zones: "
2138                                             "failed to open zone root "
2139                                             "dataset (%s): %s\n"),
2140                                             zoneroot_ds,
2141                                             libzfs_error_description(g_zfs));
2142                                         ret = zfs_err_to_be_err(g_zfs);
2143                                         if (bt.nbe_zfs_props != NULL)
2144                                                 nvlist_free(bt.nbe_zfs_props);
2145                                         goto done;
2146                                 }
2147 
2148                                 /*
2149                                  * Try to clone the zone BE again. This
2150                                  * call will end up closing the zfs
2151                                  * handle passed in whether it
2152                                  * succeeds or fails.
2153                                  */
2154                                 iret = be_clone_fs_callback(z_zhp, &bt);
2155                                 z_zhp = NULL;
2156                                 if (iret == 0) {
2157                                         break;
2158                                 } else if (iret != BE_ERR_BE_EXISTS) {
2159                                         be_print_err(gettext("be_copy_zones: "
2160                                             "failed to create zone BE clone "
2161                                             "for new zone BE %s\n"),
2162                                             new_zone_be_name);
2163                                         ret = iret;
2164                                         if (bt.nbe_zfs_props != NULL)
2165                                                 nvlist_free(bt.nbe_zfs_props);
2166                                         goto done;
2167                                 }
2168                         }
2169                         /*
2170                          * If we've exhausted the maximum number of
2171                          * tries, free the auto zone BE name and return
2172                          * error.
2173                          */
2174                         if (num_retries == BE_AUTO_NAME_MAX_TRY) {
2175                                 be_print_err(gettext("be_copy_zones: failed "
2176                                     "to create a unique auto zone BE name\n"));
2177                                 free(bt.nbe_name);
2178                                 bt.nbe_name = NULL;
2179                                 ret = BE_ERR_AUTONAME;
2180                                 if (bt.nbe_zfs_props != NULL)
2181                                         nvlist_free(bt.nbe_zfs_props);
2182                                 goto done;
2183                         }
2184                 }
2185 
2186                 if (bt.nbe_zfs_props != NULL)
2187                         nvlist_free(bt.nbe_zfs_props);
2188 
2189                 z_zhp = NULL;
2190 
2191                 if ((z_zhp = zfs_open(g_zfs, new_zoneroot_ds,
2192                     ZFS_TYPE_FILESYSTEM)) == NULL) {
2193                         be_print_err(gettext("be_copy_zones: "
2194                             "failed to open the new zone BE root dataset "
2195                             "(%s): %s\n"), new_zoneroot_ds,
2196                             libzfs_error_description(g_zfs));
2197                         ret = zfs_err_to_be_err(g_zfs);
2198                         goto done;
2199                 }
2200 
2201                 if (zfs_prop_set(z_zhp, BE_ZONE_PARENTBE_PROPERTY,
2202                     uu_string) != 0) {
2203                         be_print_err(gettext("be_copy_zones: "
2204                             "failed to set parentbe property\n"));
2205                         ZFS_CLOSE(z_zhp);
2206                         ret = zfs_err_to_be_err(g_zfs);




 335                         /* Create file system if it doesn't already exist */
 336                         if (zfs_dataset_exists(g_zfs, child_fs,
 337                             ZFS_TYPE_FILESYSTEM)) {
 338                                 continue;
 339                         }
 340                         if (zfs_create(g_zfs, child_fs, ZFS_TYPE_FILESYSTEM,
 341                             props) != 0) {
 342                                 be_print_err(gettext("be_init: failed to "
 343                                     "create BE's shared dataset (%s): %s\n"),
 344                                     child_fs, libzfs_error_description(g_zfs));
 345                                 ret = zfs_err_to_be_err(g_zfs);
 346                                 nvlist_free(props);
 347                                 goto done;
 348                         }
 349                 }
 350 
 351                 nvlist_free(props);
 352         }
 353 
 354 done:

 355         nvlist_free(bt.nbe_zfs_props);
 356 
 357         be_zfs_fini();
 358 
 359         return (ret);
 360 }
 361 
 362 /*
 363  * Function:    be_destroy
 364  * Description: Destroy a BE and all of its children datasets, snapshots and
 365  *              zones that belong to the parent BE.
 366  * Parameters:
 367  *              be_attrs - pointer to nvlist_t of attributes being passed in.
 368  *                      The following attributes are used by this function:
 369  *
 370  *                      BE_ATTR_ORIG_BE_NAME            *required
 371  *                      BE_ATTR_DESTROY_FLAGS           *optional
 372  * Return:
 373  *              BE_SUCCESS - Success
 374  *              be_errno_t - Failure


1149                         ret = zfs_err_to_be_err(g_zfs);
1150                         goto done;
1151                 }
1152 
1153                 /*
1154                  * Return the auto generated name to the caller
1155                  */
1156                 if (bt.nbe_name) {
1157                         if (nvlist_add_string(be_attrs, BE_ATTR_NEW_BE_NAME,
1158                             bt.nbe_name) != 0) {
1159                                 be_print_err(gettext("be_copy: failed to "
1160                                     "add snap name to be_attrs\n"));
1161                         }
1162                 }
1163         }
1164 
1165 done:
1166         ZFS_CLOSE(zhp);
1167         be_free_fs_list(&fld);
1168 

1169         nvlist_free(bt.nbe_zfs_props);
1170 
1171         free(bt.obe_altroot);
1172         free(new_mp);
1173 
1174         /*
1175          * If a failure occurred and we already created the datasets for
1176          * the new boot environment, destroy them.
1177          */
1178         if (ret != BE_SUCCESS && be_created) {
1179                 be_destroy_data_t       cdd = { 0 };
1180 
1181                 cdd.force_unmount = B_TRUE;
1182 
1183                 be_print_err(gettext("be_copy: "
1184                     "destroying partially created boot environment\n"));
1185 
1186                 if (getzoneid() == GLOBAL_ZONEID && be_get_uuid(bt.nbe_root_ds,
1187                     &cdd.gz_be_uuid) == 0)
1188                         (void) be_destroy_zones(bt.nbe_name, bt.nbe_root_ds,


2071                 bt.nbe_root_ds = new_zoneroot_ds;
2072 
2073                 if (nvlist_alloc(&bt.nbe_zfs_props, NV_UNIQUE_NAME, 0) != 0) {
2074                         be_print_err(gettext("be_copy_zones: "
2075                             "internal error: out of memory\n"));
2076                         ret = BE_ERR_NOMEM;
2077                         goto done;
2078                 }
2079 
2080                 /*
2081                  * The call to be_clone_fs_callback always closes the
2082                  * zfs_handle so there's no need to close z_zhp.
2083                  */
2084                 if ((iret = be_clone_fs_callback(z_zhp, &bt)) != 0) {
2085                         z_zhp = NULL;
2086                         if (iret != BE_ERR_BE_EXISTS) {
2087                                 be_print_err(gettext("be_copy_zones: "
2088                                     "failed to create zone BE clone for new "
2089                                     "zone BE %s\n"), new_zone_be_name);
2090                                 ret = iret;

2091                                 nvlist_free(bt.nbe_zfs_props);
2092                                 goto done;
2093                         }
2094                         /*
2095                          * We failed to create the new zone BE because a zone
2096                          * BE with the auto-name we generated above has since
2097                          * come into existence. Regenerate a new auto-name
2098                          * and retry.
2099                          */
2100                         for (num_retries = 1;
2101                             num_retries < BE_AUTO_NAME_MAX_TRY;
2102                             num_retries++) {
2103 
2104                                 /* Sleep 1 before retrying */
2105                                 (void) sleep(1);
2106 
2107                                 /* Generate new auto zone BE name */
2108                                 free(new_zone_be_name);
2109                                 if ((new_zone_be_name = be_auto_zone_be_name(
2110                                     zone_container_ds,
2111                                     zone_be_name)) == NULL) {
2112                                         be_print_err(gettext("be_copy_zones: "
2113                                             "failed to generate auto name "
2114                                             "for zone BE.\n"));
2115                                         ret = BE_ERR_AUTONAME;

2116                                         nvlist_free(bt.nbe_zfs_props);
2117                                         goto done;
2118                                 }
2119 
2120                                 (void) snprintf(new_zoneroot_ds,
2121                                     sizeof (new_zoneroot_ds),
2122                                     "%s/%s", zone_container_ds,
2123                                     new_zone_be_name);
2124                                 bt.nbe_name = new_zone_be_name;
2125                                 bt.nbe_root_ds = new_zoneroot_ds;
2126 
2127                                 /*
2128                                  * Get handle to original zone BE's root
2129                                  * dataset.
2130                                  */
2131                                 if ((z_zhp = zfs_open(g_zfs, zoneroot_ds,
2132                                     ZFS_TYPE_FILESYSTEM)) == NULL) {
2133                                         be_print_err(gettext("be_copy_zones: "
2134                                             "failed to open zone root "
2135                                             "dataset (%s): %s\n"),
2136                                             zoneroot_ds,
2137                                             libzfs_error_description(g_zfs));
2138                                         ret = zfs_err_to_be_err(g_zfs);

2139                                         nvlist_free(bt.nbe_zfs_props);
2140                                         goto done;
2141                                 }
2142 
2143                                 /*
2144                                  * Try to clone the zone BE again. This
2145                                  * call will end up closing the zfs
2146                                  * handle passed in whether it
2147                                  * succeeds or fails.
2148                                  */
2149                                 iret = be_clone_fs_callback(z_zhp, &bt);
2150                                 z_zhp = NULL;
2151                                 if (iret == 0) {
2152                                         break;
2153                                 } else if (iret != BE_ERR_BE_EXISTS) {
2154                                         be_print_err(gettext("be_copy_zones: "
2155                                             "failed to create zone BE clone "
2156                                             "for new zone BE %s\n"),
2157                                             new_zone_be_name);
2158                                         ret = iret;

2159                                         nvlist_free(bt.nbe_zfs_props);
2160                                         goto done;
2161                                 }
2162                         }
2163                         /*
2164                          * If we've exhausted the maximum number of
2165                          * tries, free the auto zone BE name and return
2166                          * error.
2167                          */
2168                         if (num_retries == BE_AUTO_NAME_MAX_TRY) {
2169                                 be_print_err(gettext("be_copy_zones: failed "
2170                                     "to create a unique auto zone BE name\n"));
2171                                 free(bt.nbe_name);
2172                                 bt.nbe_name = NULL;
2173                                 ret = BE_ERR_AUTONAME;

2174                                 nvlist_free(bt.nbe_zfs_props);
2175                                 goto done;
2176                         }
2177                 }
2178 

2179                 nvlist_free(bt.nbe_zfs_props);
2180 
2181                 z_zhp = NULL;
2182 
2183                 if ((z_zhp = zfs_open(g_zfs, new_zoneroot_ds,
2184                     ZFS_TYPE_FILESYSTEM)) == NULL) {
2185                         be_print_err(gettext("be_copy_zones: "
2186                             "failed to open the new zone BE root dataset "
2187                             "(%s): %s\n"), new_zoneroot_ds,
2188                             libzfs_error_description(g_zfs));
2189                         ret = zfs_err_to_be_err(g_zfs);
2190                         goto done;
2191                 }
2192 
2193                 if (zfs_prop_set(z_zhp, BE_ZONE_PARENTBE_PROPERTY,
2194                     uu_string) != 0) {
2195                         be_print_err(gettext("be_copy_zones: "
2196                             "failed to set parentbe property\n"));
2197                         ZFS_CLOSE(z_zhp);
2198                         ret = zfs_err_to_be_err(g_zfs);