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 } |
|