usr/src/lib/liborchestrator/upgrade_targets.c
changeset 26 fb9b1fd08e73
parent 0 87f703f8362e
child 137 e7a7b7942084
equal deleted inserted replaced
25:0b287ea33c56 26:fb9b1fd08e73
    30 #include <stdlib.h>
    30 #include <stdlib.h>
    31 #include <string.h>
    31 #include <string.h>
    32 #include <pthread.h>
    32 #include <pthread.h>
    33 #include <sys/types.h>
    33 #include <sys/types.h>
    34 
    34 
    35 #include "spmizones_api.h"
       
    36 #include "spmiapp_api.h"
       
    37 #include "orchestrator_private.h"
    35 #include "orchestrator_private.h"
    38 
    36 
    39 /*
    37 /*
    40  * Global variables
    38  * Global variables
    41  */
    39  */
    42 boolean_t instances_discovery_done = B_FALSE;
    40 boolean_t instances_discovery_done = B_FALSE;
    43 
    41 
    44 /*
       
    45  * local functions
       
    46  */
       
    47 void	print_space_results(FSspace **sp, char *outfile);
       
    48 /*
    42 /*
    49  * om_get_upgrade_targets
    43  * om_get_upgrade_targets
    50  * This function will return the upgrade targets (Solaris Instances)
    44  * This function will return the upgrade targets (Solaris Instances)
    51  * found on the system. All the solaris instances whether upgradable
    45  * found on the system. All the solaris instances whether upgradable
    52  * or not will be returned to the caller.
    46  * or not will be returned to the caller.
   178 /*ARGSUSED*/
   172 /*ARGSUSED*/
   179 boolean_t
   173 boolean_t
   180 om_is_upgrade_target_valid(om_handle_t handle,
   174 om_is_upgrade_target_valid(om_handle_t handle,
   181     upgrade_info_t *uinfo, om_callback_t ut_cb)
   175     upgrade_info_t *uinfo, om_callback_t ut_cb)
   182 {
   176 {
   183 	pthread_t	validate_upgrade_thread;
   177 	return (B_FALSE);
   184 	callback_args_t *cb_args;
       
   185 	int		ret;
       
   186 	char		root_slice[MAXNAMELEN];
       
   187 
       
   188 	if (uinfo == NULL) {
       
   189 		om_set_error(OM_NO_UPGRADE_TARGET);
       
   190 		return (B_FALSE);
       
   191 	}
       
   192 
       
   193 	/*
       
   194 	 * We support only solaris instance which is on UFS.
       
   195 	 * The other types of targets like zfs will be added when they
       
   196 	 * become available
       
   197 	 */
       
   198 	if (uinfo->instance_type != OM_INSTANCE_UFS) {
       
   199 		om_set_error(OM_NOT_UFS_UPGRADE_TARGET);
       
   200 		return (B_FALSE);
       
   201 	}
       
   202 
       
   203 	if (uinfo->instance.uinfo.disk_name == NULL) {
       
   204 		om_set_error(OM_NO_UPGRADE_TARGET);
       
   205 		return (B_FALSE);
       
   206 	}
       
   207 
       
   208 	if (!uinfo->upgradable)	{
       
   209 		om_set_error(OM_UPGRADE_NOT_ALLOWED);
       
   210 		return (B_FALSE);
       
   211 	}
       
   212 
       
   213 	(void) snprintf(root_slice, sizeof (root_slice), "%ss%d",
       
   214 	    uinfo->instance.uinfo.disk_name, uinfo->instance.uinfo.slice);
       
   215 	/*
       
   216 	 * Create a thread for running discovery and report progress
       
   217 	 * using the callback function.
       
   218 	 * if callback function is not provided, do not create the thread
       
   219 	 */
       
   220 	cb_args = (callback_args_t *)calloc(1, sizeof (callback_args_t));
       
   221 	if (cb_args == NULL) {
       
   222 		om_set_error(OM_NO_SPACE);
       
   223 		return (B_FALSE);
       
   224 	}
       
   225 	cb_args->cb = ut_cb;
       
   226 	cb_args->cb_type.valid.target = strdup(root_slice);
       
   227 	if (cb_args->cb_type.valid.target == NULL) {
       
   228 		om_set_error(OM_NO_SPACE);
       
   229 		free(cb_args);
       
   230 		return (B_FALSE);
       
   231 	}
       
   232 	ret = pthread_create(&validate_upgrade_thread, NULL,
       
   233 	    handle_upgrade_validation, (void *)cb_args);
       
   234 
       
   235 	if (ret != 0) {
       
   236 		om_set_error(OM_ERROR_THREAD_CREATE);
       
   237 		free(cb_args->cb_type.valid.target);
       
   238 		free(cb_args);
       
   239 		return (B_FALSE);
       
   240 	}
       
   241 	return (B_TRUE);
       
   242 }
   178 }
   243 
   179 
   244 /*
   180 /*
   245  * om_free_upgrade_targets
   181  * om_free_upgrade_targets
   246  * This function will free up the upgrade target information data
   182  * This function will free up the upgrade target information data
   391 	free(si->incorrect_zone_list);
   327 	free(si->incorrect_zone_list);
   392 	free(si->instance.uinfo.disk_name);
   328 	free(si->instance.uinfo.disk_name);
   393 	free(si->instance.uinfo.svm_info);
   329 	free(si->instance.uinfo.svm_info);
   394 	return (NULL);
   330 	return (NULL);
   395 }
   331 }
   396 
       
   397 /*
       
   398  * om_is_upgrade_target_valid
       
   399  * This function perform upgrade target validation using the
       
   400  * upgrade mechanism implemented in pfinatll
       
   401  * Input:	void *args - The arguments to initialize the callback.
       
   402  *		currently the structure containing upgrade target slice
       
   403  *		and the callback function are passed.
       
   404  * Output:	None
       
   405  * Return:	The status is returned as part of pthread_exit function
       
   406  */
       
   407 
       
   408 void *
       
   409 handle_upgrade_validation(void *args)
       
   410 {
       
   411 	callback_args_t		*cp;
       
   412 	om_callback_t		cb;
       
   413 	char			*root_slice;
       
   414 	char			*media_dir = "/cdrom";
       
   415 	Module			*media, *mod;
       
   416 	char			*meta_cluster;
       
   417 	FSspace			**space;
       
   418 	int			status;
       
   419 	int16_t			percent = 0;
       
   420 	boolean_t		zones_loaded = B_FALSE;
       
   421 
       
   422 	cp = (callback_args_t *)args;
       
   423 
       
   424 	root_slice = cp->cb_type.valid.target;
       
   425 	cb = cp->cb;
       
   426 
       
   427 	init_spmi_for_upgrade_check();
       
   428 	/*
       
   429 	 * Mount the file system to examine the instance
       
   430 	 */
       
   431 	if ((status = mount_and_add_swap(root_slice, NULL)) != 0) {
       
   432 		om_set_error(OM_BAD_UPGRADE_TARGET);
       
   433 		om_debug_print(OM_DBGLVL_ERR, "mount_and_add_swap failed\n");
       
   434 		goto huv_return;
       
   435 	}
       
   436 	percent += 10;
       
   437 	send_upgrade_validation_callback(percent, cb);
       
   438 
       
   439 	if ((mod = load_installed("/", FALSE)) == NULL) {
       
   440 		om_set_error(OM_BAD_UPGRADE_TARGET);
       
   441 		status = OM_BAD_UPGRADE_TARGET;
       
   442 		om_debug_print(OM_DBGLVL_ERR, "load_installed failed\n");
       
   443 		goto huv_return;
       
   444 	}
       
   445 	percent += 10;
       
   446 	send_upgrade_validation_callback(percent, cb);
       
   447 
       
   448 	meta_cluster = mod->sub->sub->info.mod->m_pkgid;
       
   449 
       
   450 	if (load_zones() != 0) {
       
   451 		om_set_error(OM_BAD_UPGRADE_TARGET);
       
   452 		om_debug_print(OM_DBGLVL_ERR, "load_zones failed\n");
       
   453 		status = OM_BAD_UPGRADE_TARGET;
       
   454 		goto huv_return;
       
   455 	}
       
   456 	zones_loaded = B_TRUE;
       
   457 	percent += 10;
       
   458 	send_upgrade_validation_callback(percent, cb);
       
   459 
       
   460 	/*
       
   461 	 * Load the media
       
   462 	 */
       
   463 	if ((media = add_media(media_dir)) != NULL) {
       
   464 		if (load_media(media, TRUE) != 0) {
       
   465 			om_set_error(OM_CANNOT_LOAD_MEDIA);
       
   466 			status = OM_CANNOT_LOAD_MEDIA;
       
   467 			om_debug_print(OM_DBGLVL_ERR, "load_media failed\n");
       
   468 			goto huv_return;
       
   469 		}
       
   470 	}
       
   471 	percent += 10;
       
   472 	send_upgrade_validation_callback(percent, cb);
       
   473 
       
   474 	status = upgrade_all_envs();
       
   475 	if (status != 0) {
       
   476 		om_set_error(OM_BAD_UPGRADE_TARGET);
       
   477 		om_debug_print(OM_DBGLVL_ERR, "upgrade_all_envs failed\n");
       
   478 		goto huv_return;
       
   479 	}
       
   480 
       
   481 	(void) load_view((get_default_media())->sub, get_localmedia());
       
   482 
       
   483 	status = configure_software(meta_cluster);
       
   484 
       
   485 	percent += 10;
       
   486 	send_upgrade_validation_callback(percent, cb);
       
   487 
       
   488 	if (status != 0) {
       
   489 		om_set_error(OM_BAD_UPGRADE_TARGET);
       
   490 		om_debug_print(OM_DBGLVL_ERR, "configure_software failed\n");
       
   491 		goto huv_return;
       
   492 	}
       
   493 
       
   494 	/*
       
   495 	 * Get the current file system layout
       
   496 	 */
       
   497 	space = get_current_fs_layout(TRUE);
       
   498 	if (space == NULL) {
       
   499 		om_set_error(OM_BAD_UPGRADE_TARGET);
       
   500 		status = OM_BAD_UPGRADE_TARGET;
       
   501 		om_debug_print(OM_DBGLVL_ERR, "get_current_fs_layout failed\n");
       
   502 		goto huv_return;
       
   503 	}
       
   504 
       
   505 	percent += 20;
       
   506 	send_upgrade_validation_callback(percent, cb);
       
   507 
       
   508 	status = verify_fs_layout(space, NULL, NULL);
       
   509 
       
   510 	if (status == SP_ERR_NOT_ENOUGH_SPACE) {
       
   511 		om_set_error(OM_NOT_ENOUGH_SPACE);
       
   512 		om_debug_print(OM_DBGLVL_ERR, "verify_fs_layout failed\n");
       
   513 
       
   514 		/*
       
   515 		 * Report the space required information back to the user
       
   516 		 */
       
   517 		print_space_results(space, "/tmp/space.out");
       
   518 		goto huv_return;
       
   519 	} else if (status != 0) {
       
   520 		om_set_error(OM_SPACE_CHECK_FAILURE);
       
   521 		om_debug_print(OM_DBGLVL_ERR, "verify_fs_layout failed\n");
       
   522 		goto huv_return;
       
   523 	}
       
   524 	percent += 20;
       
   525 	send_upgrade_validation_callback(percent, cb);
       
   526 	status = 0;
       
   527 
       
   528 huv_return:
       
   529 	if (zones_loaded) {
       
   530 		UmountAllZones(get_rootdir());
       
   531 	}
       
   532 	om_debug_print(OM_DBGLVL_ERR, "validation exited with status = %d\n",
       
   533 	    status);
       
   534 
       
   535 	if (umount_and_delete_swap() != 0) {
       
   536 		/*
       
   537 		 * Log the failure
       
   538 		 */
       
   539 		status = OM_CANNOT_UMOUNT_ROOT_SWAP;
       
   540 		om_set_error(OM_CANNOT_UMOUNT_ROOT_SWAP);
       
   541 		om_debug_print(OM_DBGLVL_ERR,
       
   542 		    "umount_and_delete_swap failed\n");
       
   543 	}
       
   544 	if (status == 0) {
       
   545 		percent = 100;
       
   546 	} else {
       
   547 		percent = -1;
       
   548 	}
       
   549 	send_upgrade_validation_callback(percent, cb);
       
   550 	/*
       
   551 	 * Free the arguments allocated for this thread by the caller
       
   552 	 */
       
   553 	free(cp->cb_type.valid.target);
       
   554 	free(args);
       
   555 	pthread_exit((void *)&status);
       
   556 	/* LINTED [no return statement] */
       
   557 }
       
   558 
       
   559 /*
       
   560  * send_upgrade_validation_callback
       
   561  * This function will send a callback with the percent information
       
   562  * passed as a parameter
       
   563  * Input:	percent - The percentage of validation completed
       
   564  *		cb - Callback function to be invoked
       
   565  * output:	None
       
   566  * Return:	None
       
   567  */
       
   568 void
       
   569 send_upgrade_validation_callback(int16_t percent, om_callback_t cb)
       
   570 {
       
   571 	om_callback_info_t	cb_data;
       
   572 	uintptr_t		app_data = 0;
       
   573 
       
   574 	if (cb == NULL) {
       
   575 		return;
       
   576 	}
       
   577 	cb_data.callback_type = OM_SYSTEM_VALIDATION;
       
   578 	cb_data.num_milestones = 1;
       
   579 	cb_data.curr_milestone = OM_UPGRADE_CHECK;
       
   580 	cb_data.percentage_done = percent;
       
   581 	cb(&cb_data, app_data);
       
   582 }