Changes in uspace/app/sysinst/sysinst.c [2c21595:9b95b964] in mainline
- File:
-
- 1 edited
-
uspace/app/sysinst/sysinst.c (modified) (23 diffs)
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sysinst/sysinst.c
r2c21595 r9b95b964 1 1 /* 2 * Copyright (c) 202 6Jiri Svoboda2 * Copyright (c) 2024 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 41 41 #include <errno.h> 42 42 #include <fdisk.h> 43 #include <fmgt.h>44 #include <gfx/render.h>45 #include <io/log.h>46 43 #include <loc.h> 47 44 #include <stdio.h> … … 49 46 #include <str.h> 50 47 #include <str_error.h> 51 #include <system.h>52 #include <ui/msgdialog.h>53 #include <ui/ui.h>54 #include <ui/window.h>55 48 #include <vfs/vfs.h> 56 49 #include <vol.h> 57 50 51 #include "futil.h" 58 52 #include "grub.h" 59 53 #include "rdimg.h" 60 54 #include "volume.h" 61 #include "sysinst.h"62 63 #define NAME "sysinst"64 55 65 56 /** Device to install to … … 72 63 */ 73 64 #define DEFAULT_DEV_0 "devices/\\hw\\sys\\00:01.1\\c0d0" 74 #define DEFAULT_DEV_1 "devices/\\hw\\sys\\ide1\\c0d0" 75 #define DEFAULT_DEV_2 "devices/\\hw\\sys\\00:01.0\\ide1\\c0d0" 65 #define DEFAULT_DEV_1 "devices/\\hw\\sys\\00:01.0\\ata1\\c0d0" 76 66 //#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.2\\uhci_rh\\usb01_a1\\mass-storage0\\l0" 77 /** Index of partition which we must install to (hardwired in load.cfg) */78 #define INST_PART_IDX 179 /* File system type cannot be changed without modifying core.img */80 #define INST_FSTYPE fs_ext481 67 /** Volume label for the new file system */ 82 68 #define INST_VOL_LABEL "HelenOS" … … 91 77 #define CD_MOUNT_POINT "/vol/" CD_VOL_LABEL 92 78 93 #define BOOT_FILES_SRC CD_MOUNT_POINT "/boot"79 #define BOOT_FILES_SRC CD_MOUNT_POINT 94 80 #define BOOT_BLOCK_IDX 0 /* MBR */ 95 96 #define CFG_FILES_SRC "/cfg"97 #define CFG_FILES_DEST MOUNT_POINT98 81 99 82 static const char *default_devs[] = { 100 83 DEFAULT_DEV_0, 101 84 DEFAULT_DEV_1, 102 DEFAULT_DEV_2,103 85 NULL 104 86 }; … … 110 92 }; 111 93 112 static fibril_mutex_t shutdown_lock;113 static fibril_condvar_t shutdown_cv;114 static bool shutdown_stopped;115 static bool shutdown_failed;116 117 static void sysinst_shutdown_complete(void *);118 static void sysinst_shutdown_failed(void *);119 120 static system_cb_t sysinst_system_cb = {121 .shutdown_complete = sysinst_shutdown_complete,122 .shutdown_failed = sysinst_shutdown_failed123 };124 125 static void wnd_close(ui_window_t *, void *);126 static errno_t bg_wnd_paint(ui_window_t *, void *);127 128 static ui_window_cb_t bg_window_cb = {129 .close = wnd_close,130 .paint = bg_wnd_paint131 };132 133 static ui_window_cb_t progress_window_cb = {134 .close = wnd_close135 };136 137 static void sysinst_confirm_button(ui_msg_dialog_t *, void *, unsigned);138 static void sysinst_confirm_close(ui_msg_dialog_t *, void *);139 140 static ui_msg_dialog_cb_t sysinst_confirm_cb = {141 .button = sysinst_confirm_button,142 .close = sysinst_confirm_close143 };144 145 static void sysinst_upgrade_confirm_button(ui_msg_dialog_t *, void *, unsigned);146 static void sysinst_upgrade_confirm_close(ui_msg_dialog_t *, void *);147 148 static ui_msg_dialog_cb_t sysinst_upgrade_confirm_cb = {149 .button = sysinst_upgrade_confirm_button,150 .close = sysinst_upgrade_confirm_close151 };152 153 static errno_t sysinst_restart_dlg_create(sysinst_t *);154 static void sysinst_restart_dlg_button(ui_msg_dialog_t *, void *, unsigned);155 static void sysinst_restart_dlg_close(ui_msg_dialog_t *, void *);156 157 static ui_msg_dialog_cb_t sysinst_restart_dlg_cb = {158 .button = sysinst_restart_dlg_button,159 .close = sysinst_restart_dlg_close160 };161 162 static int sysinst_start(sysinst_t *);163 static errno_t sysinst_restart(sysinst_t *);164 static void sysinst_progress_destroy(sysinst_progress_t *);165 static void sysinst_progress(sysinst_t *, const char *);166 static void sysinst_action(sysinst_t *, const char *);167 static void sysinst_error(sysinst_t *, const char *);168 static void sysinst_debug(sysinst_t *, const char *);169 170 static fmgt_exists_action_t sysinst_fmgt_exists_query(void *, fmgt_exists_t *);171 static void sysinst_fmgt_action(void *, fmgt_action_t, const char *,172 const char *);173 static void sysinst_fmgt_progress(void *, fmgt_progress_t *);174 static errno_t sysinst_eject_dev(sysinst_t *, service_id_t);175 static errno_t sysinst_eject_phys_by_mp(sysinst_t *, const char *);176 static errno_t sysinst_upgrade_confirm_create(sysinst_t *);177 178 static fmgt_cb_t sysinst_fmgt_cb = {179 .exists_query = sysinst_fmgt_exists_query,180 .action = sysinst_fmgt_action,181 .progress = sysinst_fmgt_progress182 };183 184 static void sysinst_error_msg_button(ui_msg_dialog_t *, void *, unsigned);185 static void sysinst_error_msg_close(ui_msg_dialog_t *, void *);186 187 static ui_msg_dialog_cb_t sysinst_error_msg_cb = {188 .button = sysinst_error_msg_button,189 .close = sysinst_error_msg_close190 };191 192 /** Close window.193 *194 * @param window Window195 * @param arg Argument (sysinst_t *)196 */197 static void wnd_close(ui_window_t *window, void *arg)198 {199 (void)window;200 (void)arg;201 }202 203 /** Paint background window.204 *205 * @param window Window206 * @param arg Argument (sysinst_t *)207 */208 static errno_t bg_wnd_paint(ui_window_t *window, void *arg)209 {210 sysinst_t *sysinst = (sysinst_t *)arg;211 gfx_rect_t app_rect;212 gfx_context_t *gc;213 errno_t rc;214 215 gc = ui_window_get_gc(window);216 217 rc = gfx_set_color(gc, sysinst->bg_color);218 if (rc != EOK)219 return rc;220 221 ui_window_get_app_rect(window, &app_rect);222 223 rc = gfx_fill_rect(gc, &app_rect);224 if (rc != EOK)225 return rc;226 227 rc = gfx_update(gc);228 if (rc != EOK)229 return rc;230 231 return EOK;232 }233 234 /** Installation confirm dialog OK button press.235 *236 * @param dialog Message dialog237 * @param arg Argument (sysinst_t *)238 * @param btn Button number239 * @param earg Entry argument240 */241 static void sysinst_confirm_button(ui_msg_dialog_t *dialog, void *arg,242 unsigned btn)243 {244 sysinst_t *sysinst = (sysinst_t *) arg;245 246 ui_msg_dialog_destroy(dialog);247 248 switch (btn) {249 case 0:250 /* OK */251 sysinst_start(sysinst);252 break;253 default:254 /* Cancel */255 ui_quit(sysinst->ui);256 break;257 }258 }259 260 /** Installation confirm dialog close request.261 *262 * @param dialog Message dialog263 * @param arg Argument (sysinst_t *)264 */265 static void sysinst_confirm_close(ui_msg_dialog_t *dialog, void *arg)266 {267 sysinst_t *sysinst = (sysinst_t *) arg;268 269 ui_msg_dialog_destroy(dialog);270 ui_quit(sysinst->ui);271 }272 273 /** Upgrade confirm dialog OK button press.274 *275 * @param dialog Message dialog276 * @param arg Argument (sysinst_t *)277 * @param btn Button number278 * @param earg Entry argument279 */280 static void sysinst_upgrade_confirm_button(ui_msg_dialog_t *dialog, void *arg,281 unsigned btn)282 {283 sysinst_t *sysinst = (sysinst_t *) arg;284 285 ui_msg_dialog_destroy(dialog);286 287 switch (btn) {288 case 0:289 /* OK */290 fibril_mutex_lock(&sysinst->responded_lock);291 sysinst->responded = true;292 sysinst->quit = false;293 fibril_mutex_unlock(&sysinst->responded_lock);294 fibril_condvar_signal(&sysinst->responded_cv);295 break;296 default:297 /* Cancel */298 fibril_mutex_lock(&sysinst->responded_lock);299 sysinst->responded = true;300 sysinst->quit = true;301 fibril_mutex_unlock(&sysinst->responded_lock);302 fibril_condvar_signal(&sysinst->responded_cv);303 break;304 }305 }306 307 /** Upgrade confirm dialog close request.308 *309 * @param dialog Message dialog310 * @param arg Argument (sysinst_t *)311 */312 static void sysinst_upgrade_confirm_close(ui_msg_dialog_t *dialog, void *arg)313 {314 sysinst_t *sysinst = (sysinst_t *) arg;315 316 ui_msg_dialog_destroy(dialog);317 ui_quit(sysinst->ui);318 }319 320 /** Restart system dialog OK button press.321 *322 * @param dialog Message dialog323 * @param arg Argument (sysinst_t *)324 * @param btn Button number325 * @param earg Entry argument326 */327 static void sysinst_restart_dlg_button(ui_msg_dialog_t *dialog, void *arg,328 unsigned btn)329 {330 sysinst_t *sysinst = (sysinst_t *) arg;331 332 ui_msg_dialog_destroy(dialog);333 334 (void)sysinst;335 336 switch (btn) {337 case 0:338 /* OK */339 sysinst_action(sysinst, "Ejecting installation media.");340 (void)sysinst_eject_phys_by_mp(sysinst, CD_MOUNT_POINT);341 (void)sysinst_restart(sysinst);342 break;343 default:344 /* Cancel */345 ui_quit(sysinst->ui);346 break;347 }348 }349 350 /** Restat system dialog close request.351 *352 * @param dialog Message dialog353 * @param arg Argument (sysinst_t *)354 */355 static void sysinst_restart_dlg_close(ui_msg_dialog_t *dialog, void *arg)356 {357 sysinst_t *sysinst = (sysinst_t *) arg;358 359 ui_msg_dialog_destroy(dialog);360 ui_quit(sysinst->ui);361 }362 363 /** Installation error message dialog button press.364 *365 * @param dialog Message dialog366 * @param arg Argument (sysinst_t *)367 * @param bnum Button number368 */369 static void sysinst_error_msg_button(ui_msg_dialog_t *dialog,370 void *arg, unsigned bnum)371 {372 sysinst_t *sysinst = (sysinst_t *) arg;373 374 ui_msg_dialog_destroy(dialog);375 ui_quit(sysinst->ui);376 }377 378 /** Installation error message dialog close request.379 *380 * @param dialog Message dialog381 * @param arg Argument (shutdown_dlg_t *)382 */383 static void sysinst_error_msg_close(ui_msg_dialog_t *dialog, void *arg)384 {385 sysinst_t *sysinst = (sysinst_t *) arg;386 387 ui_msg_dialog_destroy(dialog);388 ui_quit(sysinst->ui);389 }390 391 /** Create error message dialog.392 *393 * @param sysinst System installer394 * @return EOK on success or an error code395 */396 static errno_t sysinst_error_msg_create(sysinst_t *sysinst)397 {398 ui_msg_dialog_params_t params;399 ui_msg_dialog_t *dialog;400 errno_t rc;401 402 ui_msg_dialog_params_init(¶ms);403 params.caption = "Error";404 params.text = sysinst->errmsg;405 params.flags |= umdf_topmost | umdf_center;406 407 rc = ui_msg_dialog_create(sysinst->ui, ¶ms, &dialog);408 if (rc != EOK)409 return rc;410 411 ui_msg_dialog_set_cb(dialog, &sysinst_error_msg_cb, (void *)sysinst);412 413 return EOK;414 }415 416 /** Called when fmgt hits an existing file while copying.417 *418 * @param arg Argument (sysinst_t *)419 * @param exists Information about existing file420 * @return Existing file recovery action421 */422 fmgt_exists_action_t sysinst_fmgt_exists_query(void *arg, fmgt_exists_t *exists)423 {424 sysinst_t *sysinst = (sysinst_t *)arg;425 426 (void)sysinst;427 (void)exists->fname;428 429 sysinst_action(sysinst, exists->fname);430 431 /*432 * Before starting fmgt operation, the caller would specify433 * whether to overwrite existing files.434 */435 if (sysinst->overwrite)436 return fmgt_exr_overwrite;437 else438 return fmgt_exr_skip;439 }440 441 /** Called when fmgt is starting to perform action on a file.442 *443 * @param arg Argument (sysinst_t *)444 * @param action Action being performed445 * @param src Source or only path446 * @param dest Destination path or @c NULL447 */448 static void sysinst_fmgt_action(void *arg, fmgt_action_t action,449 const char *src, const char *dest)450 {451 sysinst_t *sysinst = (sysinst_t *)arg;452 char buf[128];453 454 (void)src;455 456 switch (action) {457 case fmgt_ac_create:458 snprintf(buf, sizeof(buf), "Creating %s.", src);459 sysinst_action(sysinst, buf);460 break;461 case fmgt_ac_copy:462 snprintf(buf, sizeof(buf), "Copying %s.", dest);463 sysinst_action(sysinst, buf);464 break;465 default:466 break;467 }468 }469 470 /** Called by fmgt to update on progress.471 *472 * @param arg Argument (sysinst_t *)473 * @param src Source path474 * @param dest Destination path475 */476 static void sysinst_fmgt_progress(void *arg, fmgt_progress_t *progress)477 {478 sysinst_t *sysinst = (sysinst_t *)arg;479 char buf[128];480 481 snprintf(buf, sizeof(buf), "Copied %s files, %s; "482 "current file: %s done.", progress->total_procf,483 progress->total_procb, progress->curf_percent);484 sysinst_progress(sysinst, buf);485 }486 487 /** System shutdown complete.488 *489 * @param arg Argument (shutdown_t *)490 */491 static void sysinst_shutdown_complete(void *arg)492 {493 (void)arg;494 495 fibril_mutex_lock(&shutdown_lock);496 shutdown_stopped = true;497 shutdown_failed = false;498 fibril_condvar_broadcast(&shutdown_cv);499 fibril_mutex_unlock(&shutdown_lock);500 }501 502 /** System shutdown failed.503 *504 * @param arg Argument (not used)505 */506 static void sysinst_shutdown_failed(void *arg)507 {508 (void)arg;509 510 fibril_mutex_lock(&shutdown_lock);511 shutdown_stopped = true;512 shutdown_failed = true;513 fibril_condvar_broadcast(&shutdown_cv);514 fibril_mutex_unlock(&shutdown_lock);515 }516 517 94 /** Check the if the destination device exists. 518 95 * … … 534 111 } 535 112 536 /** Find existing OS partition. 537 * 538 * @param sysinst System installer 539 * @param fdev Destination device 540 * @param rpart Place to store pointer to partition 541 * 542 * @return EOK on success or an error code 543 */ 544 static errno_t sysinst_existing_os_part_find(sysinst_t *sysinst, 545 fdisk_dev_t *fdev, fdisk_part_t **rpart) 546 { 547 fdisk_part_t *part; 548 fdisk_part_info_t pinfo; 549 errno_t rc; 550 551 sysinst_debug(sysinst, "sysinst_existing_os_part_find(): walk partitions"); 552 553 part = fdisk_part_first(fdev); 554 while (part != NULL) { 555 rc = fdisk_part_get_info(part, &pinfo); 556 if (rc != EOK) { 557 sysinst_error(sysinst, 558 "Error getting partition information."); 559 goto error; 560 } 561 562 if (pinfo.index == INST_PART_IDX && pinfo.pkind == lpk_primary) 563 break; 564 565 part = fdisk_part_next(part); 566 } 567 568 /* Partition with index INST_PART_IDX not found? */ 569 if (part == NULL) 570 return ENOENT; 571 572 /* Correct file system type? */ 573 if (pinfo.fstype != INST_FSTYPE) { 574 /* Not a usable existing partition. */ 575 return ENOENT; 576 } 577 578 sysinst_debug(sysinst, "sysinst_existing_os_part_find(): OK"); 579 sysinst->psvc_id = pinfo.svc_id; 580 *rpart = part; 581 return EOK; 582 error: 583 return rc; 584 } 585 586 /** Create installation partition. 587 * 588 * @param sysinst System installer 589 * @param fdev Destination device 590 * 591 * @return EOK on success or an error code 592 */ 593 static errno_t sysinst_inst_part_create(sysinst_t *sysinst, fdisk_dev_t *fdev) 594 { 113 /** Label the destination device. 114 * 115 * @param dev Disk device to label 116 * @param psvc_id Place to store service ID of the created partition 117 * 118 * @return EOK on success or an error code 119 */ 120 static errno_t sysinst_label_dev(const char *dev, service_id_t *psvc_id) 121 { 122 fdisk_t *fdisk; 123 fdisk_dev_t *fdev; 595 124 fdisk_part_t *part; 596 125 fdisk_part_spec_t pspec; 597 126 fdisk_part_info_t pinfo; 598 127 capa_spec_t capa; 599 errno_t rc; 600 601 sysinst_debug(sysinst, "sysinst_inst_part_create(): get maximum available block"); 128 service_id_t sid; 129 errno_t rc; 130 131 printf("sysinst_label_dev(): get service ID '%s'\n", dev); 132 rc = loc_service_get_id(dev, &sid, 0); 133 if (rc != EOK) 134 return rc; 135 136 printf("sysinst_label_dev(): open device\n"); 137 138 rc = fdisk_create(&fdisk); 139 if (rc != EOK) { 140 printf("Error initializing fdisk.\n"); 141 return rc; 142 } 143 144 rc = fdisk_dev_open(fdisk, sid, &fdev); 145 if (rc != EOK) { 146 printf("Error opening device.\n"); 147 return rc; 148 } 149 150 printf("sysinst_label_dev(): create mount directory\n"); 151 152 rc = vfs_link_path(MOUNT_POINT, KIND_DIRECTORY, NULL); 153 if (rc != EOK) 154 return rc; 155 156 printf("sysinst_label_dev(): create label\n"); 157 158 rc = fdisk_label_create(fdev, lt_mbr); 159 if (rc != EOK) { 160 printf("Error creating label: %s.\n", str_error(rc)); 161 return rc; 162 } 163 164 printf("sysinst_label_dev(): create partition\n"); 602 165 603 166 rc = fdisk_part_get_max_avail(fdev, spc_pri, &capa); 604 167 if (rc != EOK) { 605 sysinst_error(sysinst, 606 "Error getting available capacity."); 607 goto error; 168 printf("Error getting available capacity: %s.\n", str_error(rc)); 169 return rc; 608 170 } 609 171 … … 611 173 pspec.capacity = capa; 612 174 pspec.pkind = lpk_primary; 613 pspec.fstype = INST_FSTYPE; /* Cannot be changed without modifying core.img */175 pspec.fstype = fs_ext4; /* Cannot be changed without modifying core.img */ 614 176 pspec.mountp = MOUNT_POINT; 615 pspec.index = INST_PART_IDX; /* Cannot be changed without modifying core.img */616 177 pspec.label = INST_VOL_LABEL; 617 178 618 179 rc = fdisk_part_create(fdev, &pspec, &part); 619 180 if (rc != EOK) { 620 sysinst_error(sysinst, "Error creating partition.");621 goto error;181 printf("Error creating partition.\n"); 182 return rc; 622 183 } 623 184 624 185 rc = fdisk_part_get_info(part, &pinfo); 625 186 if (rc != EOK) { 626 sysinst_error(sysinst, "Error getting partition information."); 627 goto error; 628 } 629 630 sysinst_debug(sysinst, "sysinst_inst_part_create(): OK"); 631 sysinst->psvc_id = pinfo.svc_id; 632 return EOK; 633 error: 634 return rc; 635 } 636 637 /** Label and mount the destination device. 638 * 639 * @param sysinst System installer 640 * @param dev Disk device to label 641 * 642 * @return EOK on success or an error code 643 */ 644 static errno_t sysinst_label_dev(sysinst_t *sysinst, const char *dev) 645 { 646 fdisk_t *fdisk = NULL; 647 fdisk_dev_t *fdev = NULL; 648 fdisk_part_t *part; 649 fdisk_label_info_t linfo; 650 bool create_label = false; 651 bool dir_created = false; 652 bool label_created = false; 653 service_id_t sid; 654 errno_t rc; 655 656 sysinst_debug(sysinst, "sysinst_label_dev(): get service ID"); 657 658 rc = loc_service_get_id(dev, &sid, 0); 659 if (rc != EOK) 660 goto error; 661 662 sysinst_debug(sysinst, "sysinst_label_dev(): open device"); 663 664 rc = fdisk_create(&fdisk); 665 if (rc != EOK) { 666 sysinst_error(sysinst, "Error initializing fdisk."); 667 goto error; 668 } 669 670 rc = fdisk_dev_open(fdisk, sid, &fdev); 671 if (rc != EOK) { 672 sysinst_error(sysinst, "Error opening device."); 673 goto error; 674 } 675 676 sysinst_debug(sysinst, "sysinst_label_dev(): create mount directory"); 677 678 rc = vfs_link_path(MOUNT_POINT, KIND_DIRECTORY, NULL); 679 if (rc != EOK) { 680 sysinst_error(sysinst, "Error creating mount directory."); 681 goto error; 682 } 683 684 dir_created = true; 685 686 sysinst_debug(sysinst, "sysinst_label_dev(): create label"); 687 688 rc = fdisk_label_get_info(fdev, &linfo); 689 if (rc != EOK) { 690 sysinst_error(sysinst, "Error analyzing device."); 691 goto error; 692 } 693 694 switch (linfo.ltype) { 695 case lt_none: 696 /* need to create label */ 697 create_label = true; 698 break; 699 case lt_mbr: 700 /* MBR label already present */ 701 break; 702 default: 703 /* a different type of label already present */ 704 sysinst_error(sysinst, "Disk contains unusable label."); 705 goto error; 706 } 707 708 /* Need to create label? */ 709 if (create_label) { 710 rc = fdisk_label_create(fdev, lt_mbr); 711 if (rc != EOK) { 712 sysinst_error(sysinst, "Error creating label."); 713 goto error; 714 } 715 } 716 717 label_created = true; 718 719 sysinst_debug(sysinst, "sysinst_label_dev(): create partition"); 720 721 /* Existing OS partition? */ 722 rc = sysinst_existing_os_part_find(sysinst, fdev, &part); 723 if (rc == EOK) { 724 /* Open dialog to confirm that user wants to upgrade. */ 725 rc = sysinst_upgrade_confirm_create(sysinst); 726 if (rc != EOK) { 727 sysinst_error(sysinst, "Cannot create window."); 728 goto error; 729 } 730 731 fibril_mutex_lock(&sysinst->responded_lock); 732 while (!sysinst->responded) 733 fibril_condvar_wait(&sysinst->responded_cv, 734 &sysinst->responded_lock); 735 fibril_mutex_unlock(&sysinst->responded_lock); 736 737 /* User decided not to upgrade existing installation? */ 738 if (sysinst->quit) { 739 (void)vfs_unlink_path(MOUNT_POINT); 740 return EOK; 741 } 742 743 /* Set mount point for installation partition. */ 744 rc = fdisk_part_set_mountp(part, MOUNT_POINT); 745 if (rc != EOK) { 746 sysinst_error(sysinst, "Cannot mount installation " 747 "partition."); 748 goto error; 749 } 750 751 /* performing OS upgrade */ 752 sysinst->oper = sio_upgrade; 753 if (sysinst->progress != NULL) { 754 (void)ui_label_set_text(sysinst->progress->label, 755 "Upgrading system. Please wait..."); 756 (void)ui_label_paint(sysinst->progress->label); 757 (void)ui_window_set_caption(sysinst->bgwindow, 758 "System Upgrade"); 759 } 760 } else { 761 /* Create installation partition. */ 762 rc = sysinst_inst_part_create(sysinst, fdev); 763 if (rc != EOK) 764 goto error; 765 766 /* performing initial OS installation */ 767 sysinst->oper = sio_install; 768 } 769 770 return EOK; 771 error: 772 if (label_created) 773 fdisk_label_destroy(fdev); 774 if (dir_created) 775 (void)vfs_unlink_path(MOUNT_POINT); 776 if (fdev != NULL) 777 fdisk_dev_close(fdev); 778 if (fdisk != NULL) 779 fdisk_destroy(fdisk); 780 return rc; 781 } 782 783 /** Finish/unmount destination device. 784 * 785 * @param sysinst System installer 786 * 787 * @return EOK on success or an error code 788 */ 789 static errno_t sysinst_finish_dev(sysinst_t *sysinst) 790 { 791 errno_t rc; 792 793 sysinst_debug(sysinst, "sysinst_finish_dev(): eject target volume"); 794 rc = sysinst_eject_dev(sysinst, sysinst->psvc_id); 795 if (rc != EOK) 796 return rc; 797 798 sysinst_debug(sysinst, "sysinst_finish_dev(): " 799 "deleting mount directory"); 800 (void)vfs_unlink_path(MOUNT_POINT); 801 187 printf("Error getting partition information.\n"); 188 return rc; 189 } 190 191 printf("sysinst_label_dev(): OK\n"); 192 *psvc_id = pinfo.svc_id; 802 193 return EOK; 803 194 } … … 805 196 /** Set up system volume structure. 806 197 * 807 * @param sysinst System installer 808 * @return EOK on success or an error code 809 */ 810 static errno_t sysinst_setup_sysvol(sysinst_t *sysinst) 198 * @return EOK on success or an error code 199 */ 200 static errno_t sysinst_setup_sysvol(void) 811 201 { 812 202 errno_t rc; 813 203 char *path = NULL; 814 204 const char **cp; 815 fmgt_flist_t *flist = NULL;816 205 int rv; 817 206 … … 825 214 826 215 rc = vfs_link_path(path, KIND_DIRECTORY, NULL); 827 if (rc != EOK && rc != EEXIST) {828 sysinst_error(sysinst, "Error creating directory.");216 if (rc != EOK) { 217 printf("Error creating directory '%s'.\n", path); 829 218 goto error; 830 219 } … … 838 227 path = NULL; 839 228 840 /* Copy initial configuration files */841 842 log_msg(LOG_DEFAULT, LVL_NOTE,843 "sysinst_copy_boot_files(): copy initial configuration files");844 845 rc = fmgt_flist_create(&flist);846 if (rc != EOK)847 goto error;848 849 rc = fmgt_flist_append(flist, CFG_FILES_SRC);850 if (rc != EOK)851 goto error;852 853 /* Do not overwrite configuration files. */854 sysinst->overwrite = false;855 rc = fmgt_copy(sysinst->fmgt, flist, CFG_FILES_DEST);856 if (rc != EOK) {857 sysinst_error(sysinst, "Error copying initial configuration "858 "files.");859 goto error;860 }861 862 fmgt_flist_destroy(flist);863 log_msg(LOG_DEFAULT, LVL_NOTE,864 "sysinst_copy_boot_files(): copy initial configuration files OK");865 229 return EOK; 866 230 error: 867 if (flist != NULL)868 fmgt_flist_destroy(flist);869 231 if (path != NULL) 870 232 free(path); … … 876 238 * @return EOK on success or an error code 877 239 */ 878 static errno_t sysinst_copy_boot_files(sysinst_t *sysinst) 879 { 880 fmgt_flist_t *flist = NULL; 881 errno_t rc; 882 883 log_msg(LOG_DEFAULT, LVL_NOTE, 884 "sysinst_copy_boot_files(): copy bootloader files"); 885 rc = fmgt_flist_create(&flist); 886 if (rc != EOK) 887 goto error; 888 889 rc = fmgt_flist_append(flist, BOOT_FILES_SRC); 890 if (rc != EOK) 891 goto error; 892 893 /* Overwrite boot files with new ones during upgrade. */ 894 sysinst->overwrite = true; 895 rc = fmgt_copy(sysinst->fmgt, flist, MOUNT_POINT); 896 if (rc != EOK) { 897 sysinst_error(sysinst, "Error copying bootloader " 898 "files."); 899 goto error; 900 } 901 902 fmgt_flist_destroy(flist); 903 sysinst_debug(sysinst, "sysinst_copy_boot_files(): OK"); 904 return EOK; 905 error: 906 if (flist != NULL) 907 fmgt_flist_destroy(flist); 908 return rc; 240 static errno_t sysinst_copy_boot_files(void) 241 { 242 errno_t rc; 243 244 printf("sysinst_copy_boot_files(): copy bootloader files\n"); 245 rc = futil_rcopy_contents(BOOT_FILES_SRC, MOUNT_POINT); 246 if (rc != EOK) 247 return rc; 248 249 printf("sysinst_copy_boot_files(): OK\n"); 250 return EOK; 909 251 } 910 252 911 253 /** Set up configuration in the initial RAM disk. 912 254 * 913 * @param sysinst System installer 914 * @return EOK on success or an error code 915 */ 916 static errno_t sysinst_customize_initrd(sysinst_t *sysinst) 255 * @return EOK on success or an error code 256 */ 257 static errno_t sysinst_customize_initrd(void) 917 258 { 918 259 errno_t rc; … … 926 267 rc = rd_img_open(MOUNT_POINT "/boot/initrd.img", &rdpath, &rd); 927 268 if (rc != EOK) { 928 sysinst_error(sysinst, "Error opening initial RAM disk image.");269 printf("Error opening initial RAM disk image.\n"); 929 270 goto error; 930 271 } 931 272 932 rv = asprintf(&path, "%s%s", rdpath, "/cfg/ initvol.sif");273 rv = asprintf(&path, "%s%s", rdpath, "/cfg/volsrv.sif"); 933 274 if (rv < 0) { 934 275 rc = ENOMEM; … … 936 277 } 937 278 938 sysinst_debug(sysinst, "Configuring volume server."); 939 279 printf("Configuring volume server.\n"); 940 280 rc = vol_volumes_create(path, &volumes); 941 281 if (rc != EOK) { 942 sysinst_error(sysinst, 943 "Error creating volume server configuration."); 282 printf("Error creating volume server configuration.\n"); 944 283 rc = EIO; 945 284 goto error; 946 285 } 947 286 948 sysinst_debug(sysinst, "Configuring volume server: look up volume");287 printf("Configuring volume server: look up volume\n"); 949 288 rc = vol_volume_lookup_ref(volumes, INST_VOL_LABEL, &volume); 950 289 if (rc != EOK) { 951 sysinst_error(sysinst, 952 "Error creating volume server configuration."); 290 printf("Error creating volume server configuration.\n"); 953 291 rc = EIO; 954 292 goto error; 955 293 } 956 294 957 sysinst_debug(sysinst, "Configuring volume server: set mount point");295 printf("Configuring volume server: set mount point\n"); 958 296 rc = vol_volume_set_mountp(volume, INST_VOL_MP); 959 297 if (rc != EOK) { 960 sysinst_error(sysinst, 961 "Error creating system partition configuration."); 298 printf("Error creating system partition configuration.\n"); 962 299 rc = EIO; 963 300 goto error; 964 301 } 965 302 966 rc = vol_volumes_sync(volumes); 967 if (rc != EOK) { 968 sysinst_error(sysinst, "Error saving volume confiuration."); 969 goto error; 970 } 971 972 log_msg(LOG_DEFAULT, LVL_NOTE, 973 "Configuring volume server: delete reference"); 303 printf("Configuring volume server: delete reference\n"); 974 304 vol_volume_del_ref(volume); 975 305 volume = NULL; 976 log_msg(LOG_DEFAULT, LVL_NOTE, 977 "Configuring volume server: destroy volumes object"); 306 printf("Configuring volume server: destroy volumes object\n"); 978 307 vol_volumes_destroy(volumes); 979 308 volumes = NULL; … … 981 310 rc = rd_img_close(rd); 982 311 if (rc != EOK) { 983 sysinst_error(sysinst, "Error closing initial RAM disk image.");312 printf("Error closing initial RAM disk image.\n"); 984 313 rc = EIO; 985 314 goto error; … … 1020 349 } 1021 350 1022 /** Return file contents as a heap-allocated block of bytes.1023 *1024 * @param srcp File path1025 * @param rdata Place to store pointer to data1026 * @param rsize Place to store size of data1027 *1028 * @return EOK on success, ENOENT if failed to open file, EIO on other1029 * I/O error, ENOMEM if out of memory1030 */1031 static errno_t sysinst_get_file(const char *srcp, void **rdata, size_t *rsize)1032 {1033 int sf;1034 size_t nr;1035 errno_t rc;1036 size_t fsize;1037 char *data;1038 vfs_stat_t st;1039 1040 rc = vfs_lookup_open(srcp, WALK_REGULAR, MODE_READ, &sf);1041 if (rc != EOK)1042 return ENOENT;1043 1044 if (vfs_stat(sf, &st) != EOK) {1045 vfs_put(sf);1046 return EIO;1047 }1048 1049 fsize = st.size;1050 1051 data = calloc(fsize, 1);1052 if (data == NULL) {1053 vfs_put(sf);1054 return ENOMEM;1055 }1056 1057 rc = vfs_read(sf, (aoff64_t []) { 0 }, data, fsize, &nr);1058 if (rc != EOK || nr != fsize) {1059 vfs_put(sf);1060 free(data);1061 return EIO;1062 }1063 1064 (void) vfs_put(sf);1065 *rdata = data;1066 *rsize = fsize;1067 1068 return EOK;1069 }1070 1071 351 /** Copy boot blocks. 1072 352 * 1073 353 * Install Grub's boot blocks. 1074 354 * 1075 * @param sysinst System installer1076 355 * @param devp Disk device 1077 356 * @return EOK on success or an error code 1078 357 */ 1079 static errno_t sysinst_copy_boot_blocks( sysinst_t *sysinst,const char *devp)358 static errno_t sysinst_copy_boot_blocks(const char *devp) 1080 359 { 1081 360 void *boot_img; … … 1091 370 errno_t rc; 1092 371 1093 log_msg(LOG_DEFAULT, LVL_NOTE, 1094 "sysinst_copy_boot_blocks: Read boot block image."); 1095 1096 rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/boot.img", 372 printf("sysinst_copy_boot_blocks: Read boot block image.\n"); 373 rc = futil_get_file(BOOT_FILES_SRC "/boot/grub/i386-pc/boot.img", 1097 374 &boot_img, &boot_img_size); 1098 if (rc != EOK || boot_img_size != 512) { 1099 sysinst_error(sysinst, "Error reading boot block image."); 375 if (rc != EOK || boot_img_size != 512) 1100 376 return EIO; 1101 } 1102 1103 log_msg(LOG_DEFAULT, LVL_NOTE, 1104 "sysinst_copy_boot_blocks: Read GRUB core image."); 1105 1106 rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/core.img", 377 378 printf("sysinst_copy_boot_blocks: Read GRUB core image.\n"); 379 rc = futil_get_file(BOOT_FILES_SRC "/boot/grub/i386-pc/core.img", 1107 380 &core_img, &core_img_size); 1108 if (rc != EOK) { 1109 sysinst_error(sysinst, "Error reading GRUB core image."); 381 if (rc != EOK) 1110 382 return EIO; 1111 } 1112 1113 log_msg(LOG_DEFAULT, LVL_NOTE, 1114 "sysinst_copy_boot_blocks: get service ID."); 1115 383 384 printf("sysinst_copy_boot_blocks: get service ID.\n"); 1116 385 rc = loc_service_get_id(devp, &sid, 0); 1117 386 if (rc != EOK) 1118 387 return rc; 1119 388 1120 log_msg(LOG_DEFAULT, LVL_NOTE, 1121 "sysinst_copy_boot_blocks: block_init."); 1122 389 printf("sysinst_copy_boot_blocks: block_init.\n"); 1123 390 rc = block_init(sid); 1124 if (rc != EOK) { 1125 sysinst_error(sysinst, "Error opening block device."); 1126 return rc; 1127 } 1128 1129 log_msg(LOG_DEFAULT, LVL_NOTE, 1130 "sysinst_copy_boot_blocks: get block size"); 1131 391 if (rc != EOK) 392 return rc; 393 394 printf("sysinst_copy_boot_blocks: get block size\n"); 1132 395 rc = block_get_bsize(sid, &bsize); 1133 if (rc != EOK) { 1134 sysinst_error(sysinst, "Error getting block size."); 1135 return rc; 1136 } 396 if (rc != EOK) 397 return rc; 1137 398 1138 399 if (bsize != 512) { 1139 sysinst_error(sysinst, "Device block size != 512.");400 printf("Device block size != 512.\n"); 1140 401 return EIO; 1141 402 } 1142 403 1143 log_msg(LOG_DEFAULT, LVL_NOTE, 1144 "sysinst_copy_boot_blocks: read boot block"); 1145 404 printf("sysinst_copy_boot_blocks: read boot block\n"); 1146 405 rc = block_read_direct(sid, BOOT_BLOCK_IDX, 1, bbuf); 1147 if (rc != EOK) { 1148 sysinst_error(sysinst, "Error reading boot block."); 406 if (rc != EOK) 1149 407 return EIO; 1150 }1151 408 1152 409 core_start = 16; … … 1160 417 --bl; 1161 418 if ((void *)bl < core_img) { 1162 sysinst_error(sysinst, 1163 "No block terminator in core image."); 419 printf("No block terminator in core image.\n"); 1164 420 return EIO; 1165 421 } … … 1175 431 set_unaligned_u64le(bbuf + grub_boot_machine_kernel_sector, core_start); 1176 432 1177 log_msg(LOG_DEFAULT, LVL_NOTE, 1178 "sysinst_copy_boot_blocks: write boot block"); 1179 433 printf("sysinst_copy_boot_blocks: write boot block\n"); 1180 434 rc = block_write_direct(sid, BOOT_BLOCK_IDX, 1, bbuf); 1181 if (rc != EOK) { 1182 sysinst_error(sysinst, "Error writing boot block."); 435 if (rc != EOK) 1183 436 return EIO; 1184 } 1185 1186 log_msg(LOG_DEFAULT, LVL_NOTE, 1187 "sysinst_copy_boot_blocks: write core blocks"); 1188 437 438 printf("sysinst_copy_boot_blocks: write core blocks\n"); 1189 439 /* XXX Must pad last block with zeros */ 1190 440 rc = block_write_direct(sid, core_start, core_blocks, core_img); 1191 if (rc != EOK) { 1192 sysinst_error(sysinst, "Error writing GRUB core blocks."); 441 if (rc != EOK) 1193 442 return EIO; 1194 } 1195 1196 log_msg(LOG_DEFAULT, LVL_NOTE, 1197 "sysinst_copy_boot_blocks: OK."); 1198 443 444 printf("sysinst_copy_boot_blocks: OK.\n"); 1199 445 return EOK; 1200 446 } … … 1202 448 /** Eject installation volume. 1203 449 * 1204 * @param sysinst System installer 1205 * @param part_id Partition service ID 1206 * @return EOK on success or an error code 1207 */ 1208 static errno_t sysinst_eject_dev(sysinst_t *sysinst, service_id_t part_id) 450 * @param psvc_id Partition service ID 451 */ 452 static errno_t sysinst_eject_dev(service_id_t part_id) 1209 453 { 1210 454 vol_t *vol = NULL; … … 1213 457 rc = vol_create(&vol); 1214 458 if (rc != EOK) { 1215 sysinst_error(sysinst, "Error contacting volume service.");459 printf("Error contacting volume service.\n"); 1216 460 goto out; 1217 461 } 1218 462 1219 rc = vol_part_eject(vol, part_id , vef_none);1220 if (rc != EOK) { 1221 sysinst_error(sysinst, "Error ejecting volume.");463 rc = vol_part_eject(vol, part_id); 464 if (rc != EOK) { 465 printf("Error ejecting volume.\n"); 1222 466 goto out; 1223 467 } … … 1229 473 } 1230 474 1231 /** Physically eject volume by mount point.1232 *1233 * @param sysinst System installer1234 * @param path Mount point1235 * @return EOK on success or an error code1236 */1237 static errno_t sysinst_eject_phys_by_mp(sysinst_t *sysinst, const char *path)1238 {1239 vol_t *vol = NULL;1240 sysarg_t part_id;1241 errno_t rc;1242 1243 log_msg(LOG_DEFAULT, LVL_NOTE,1244 "sysinst_eject_phys_by_mp(%s)", path);1245 1246 rc = vol_create(&vol);1247 if (rc != EOK) {1248 sysinst_error(sysinst, "Error contacting volume service.");1249 goto out;1250 }1251 1252 log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_by_mp: mp='%s'\n",1253 path);1254 rc = vol_part_by_mp(vol, path, &part_id);1255 if (rc != EOK) {1256 sysinst_error(sysinst,1257 "Error finding installation media mount point.");1258 goto out;1259 }1260 1261 log_msg(LOG_DEFAULT, LVL_NOTE, "eject svc_id %lu", (unsigned long)part_id);1262 rc = vol_part_eject(vol, part_id, vef_physical);1263 if (rc != EOK) {1264 sysinst_error(sysinst, "Error ejecting volume.");1265 goto out;1266 }1267 1268 rc = EOK;1269 out:1270 vol_destroy(vol);1271 return rc;1272 }1273 1274 /** Restart the system.1275 *1276 * @param sysinst System installer1277 * @return EOK on success or an error code1278 */1279 static errno_t sysinst_restart(sysinst_t *sysinst)1280 {1281 errno_t rc;1282 system_t *system;1283 1284 fibril_mutex_initialize(&shutdown_lock);1285 fibril_condvar_initialize(&shutdown_cv);1286 shutdown_stopped = false;1287 shutdown_failed = false;1288 1289 sysinst_action(sysinst, "Restarting the system.");1290 1291 rc = system_open(SYSTEM_DEFAULT, &sysinst_system_cb, NULL, &system);1292 if (rc != EOK) {1293 sysinst_error(sysinst,1294 "Failed opening system control service.");1295 return rc;1296 }1297 1298 rc = system_restart(system);1299 if (rc != EOK) {1300 system_close(system);1301 sysinst_error(sysinst, "Failed requesting system restart.");1302 return rc;1303 }1304 1305 fibril_mutex_lock(&shutdown_lock);1306 sysinst_debug(sysinst, "The system is shutting down...");1307 1308 while (!shutdown_stopped)1309 fibril_condvar_wait(&shutdown_cv, &shutdown_lock);1310 1311 if (shutdown_failed) {1312 sysinst_error(sysinst, "Shutdown failed.");1313 system_close(system);1314 return rc;1315 }1316 1317 log_msg(LOG_DEFAULT, LVL_NOTE,1318 "Shutdown complete. It is now safe to remove power.");1319 1320 /* Sleep forever */1321 while (true)1322 fibril_condvar_wait(&shutdown_cv, &shutdown_lock);1323 1324 fibril_mutex_unlock(&shutdown_lock);1325 1326 system_close(system);1327 return 0;1328 1329 }1330 1331 475 /** Install system to a device. 1332 476 * 1333 * @parma sysinst System installer1334 477 * @param dev Device to install to. 1335 478 * @return EOK on success or an error code 1336 479 */ 1337 static errno_t sysinst_install(sysinst_t *sysinst, const char *dev) 1338 { 1339 errno_t rc; 1340 bool clean_dev = false; 1341 1342 sysinst_action(sysinst, "Creating device label and file system."); 1343 1344 rc = sysinst_label_dev(sysinst, dev); 1345 if (rc != EOK) 1346 goto error; 1347 if (sysinst->quit) 1348 return EOK; 1349 1350 clean_dev = true; 1351 1352 sysinst_action(sysinst, "Creating system directory structure."); 1353 rc = sysinst_setup_sysvol(sysinst); 1354 if (rc != EOK) 1355 goto error; 1356 1357 sysinst_action(sysinst, "Copying boot files."); 1358 rc = sysinst_copy_boot_files(sysinst); 1359 if (rc != EOK) 1360 goto error; 1361 1362 sysinst_action(sysinst, "Configuring the system."); 1363 rc = sysinst_customize_initrd(sysinst); 1364 if (rc != EOK) 1365 goto error; 1366 1367 sysinst_action(sysinst, "Finishing system volume."); 1368 rc = sysinst_finish_dev(sysinst); 1369 if (rc != EOK) 1370 goto error; 1371 1372 clean_dev = false; 1373 1374 sysinst_action(sysinst, "Installing boot blocks."); 1375 rc = sysinst_copy_boot_blocks(sysinst, dev); 1376 if (rc != EOK) 1377 return rc; 1378 1379 return EOK; 1380 error: 1381 if (clean_dev) 1382 (void)sysinst_finish_dev(sysinst); 1383 return rc; 1384 } 1385 1386 /** Installation fibril. 1387 * 1388 * @param arg Argument (sysinst_t *) 1389 * @return EOK on success or an error code 1390 */ 1391 static errno_t sysinst_install_fibril(void *arg) 1392 { 1393 sysinst_t *sysinst = (sysinst_t *)arg; 480 static errno_t sysinst_install(const char *dev) 481 { 482 errno_t rc; 483 service_id_t psvc_id; 484 485 rc = sysinst_label_dev(dev, &psvc_id); 486 if (rc != EOK) 487 return rc; 488 489 printf("FS created and mounted. Creating system directory structure.\n"); 490 rc = sysinst_setup_sysvol(); 491 if (rc != EOK) 492 return rc; 493 494 printf("Directories created. Copying boot files.\n"); 495 rc = sysinst_copy_boot_files(); 496 if (rc != EOK) 497 return rc; 498 499 printf("Boot files done. Configuring the system.\n"); 500 rc = sysinst_customize_initrd(); 501 if (rc != EOK) 502 return rc; 503 504 printf("Boot files done. Installing boot blocks.\n"); 505 rc = sysinst_copy_boot_blocks(dev); 506 if (rc != EOK) 507 return rc; 508 509 printf("Ejecting device.\n"); 510 rc = sysinst_eject_dev(psvc_id); 511 if (rc != EOK) 512 return rc; 513 514 return EOK; 515 } 516 517 int main(int argc, char *argv[]) 518 { 1394 519 unsigned i; 1395 520 errno_t rc; 1396 1397 (void)sysinst;1398 521 1399 522 i = 0; … … 1402 525 if (rc == EOK) 1403 526 break; 1404 ++i;1405 527 } 1406 528 1407 529 if (default_devs[i] == NULL) { 1408 sysinst_error(sysinst, "Cannot determine installation device."); 1409 rc = ENOENT; 1410 goto error; 1411 } 1412 1413 rc = sysinst_install(sysinst, default_devs[i]); 1414 if (rc != EOK) 1415 goto error; 1416 1417 sysinst_progress_destroy(sysinst->progress); 1418 sysinst->progress = NULL; 1419 1420 /* User decided not to upgrade system? */ 1421 if (sysinst->quit) { 1422 ui_quit(sysinst->ui); 1423 return EOK; 1424 } 1425 1426 rc = sysinst_restart_dlg_create(sysinst); 1427 if (rc != EOK) 1428 goto error; 1429 1430 return EOK; 1431 error: 1432 ui_lock(sysinst->ui); 1433 sysinst_progress_destroy(sysinst->progress); 1434 (void)sysinst_error_msg_create(sysinst); 1435 ui_unlock(sysinst->ui); 1436 return rc; 1437 } 1438 1439 /** Create installation progress window. 1440 * 1441 * @param sysinst System installer 1442 * @param rprogress Place to store pointer to new progress window 1443 * @return EOK on success or an error code 1444 */ 1445 static errno_t sysinst_progress_create(sysinst_t *sysinst, 1446 sysinst_progress_t **rprogress) 1447 { 1448 ui_wnd_params_t params; 1449 ui_window_t *window = NULL; 1450 gfx_rect_t rect; 1451 gfx_rect_t arect; 1452 ui_resource_t *ui_res; 1453 sysinst_progress_t *progress; 1454 ui_fixed_t *fixed = NULL; 1455 errno_t rc; 1456 1457 ui_wnd_params_init(¶ms); 1458 params.caption = "System Installation"; 1459 params.style &= ~ui_wds_titlebar; 1460 params.flags |= ui_wndf_topmost; 1461 params.placement = ui_wnd_place_center; 1462 if (ui_is_textmode(sysinst->ui)) { 1463 params.rect.p0.x = 0; 1464 params.rect.p0.y = 0; 1465 params.rect.p1.x = 64; 1466 params.rect.p1.y = 7; 1467 } else { 1468 params.rect.p0.x = 0; 1469 params.rect.p0.y = 0; 1470 params.rect.p1.x = 500; 1471 params.rect.p1.y = 90; 1472 } 1473 1474 progress = calloc(1, sizeof(sysinst_progress_t)); 1475 if (progress == NULL) { 1476 rc = ENOMEM; 1477 sysinst_error(sysinst, "Out of memory."); 1478 goto error; 1479 } 1480 1481 rc = ui_window_create(sysinst->ui, ¶ms, &window); 1482 if (rc != EOK) { 1483 sysinst_error(sysinst, "Error creating window."); 1484 goto error; 1485 } 1486 1487 ui_window_set_cb(window, &progress_window_cb, (void *)sysinst); 1488 1489 ui_res = ui_window_get_res(window); 1490 1491 rc = ui_fixed_create(&fixed); 1492 if (rc != EOK) { 1493 sysinst_error(sysinst, "Error creating fixed layout."); 1494 goto error; 1495 } 1496 1497 /* Installing/upgrading system line */ 1498 rc = ui_label_create(ui_res, "Installing system. Please wait...", 1499 &progress->label); 1500 if (rc != EOK) { 1501 sysinst_error(sysinst, "Error creating label."); 1502 goto error; 1503 } 1504 1505 ui_window_get_app_rect(window, &arect); 1506 1507 if (ui_is_textmode(sysinst->ui)) { 1508 rect.p0.x = arect.p0.x; 1509 rect.p0.y = arect.p0.y; 1510 rect.p1.x = arect.p1.x; 1511 rect.p1.y = 2; 1512 } else { 1513 rect.p0.x = arect.p0.x; 1514 rect.p0.y = arect.p0.y; 1515 rect.p1.x = arect.p1.x; 1516 rect.p1.y = 30; 1517 } 1518 ui_label_set_rect(progress->label, &rect); 1519 ui_label_set_halign(progress->label, gfx_halign_center); 1520 ui_label_set_valign(progress->label, gfx_valign_center); 1521 1522 rc = ui_fixed_add(fixed, ui_label_ctl(progress->label)); 1523 if (rc != EOK) { 1524 sysinst_error(sysinst, "Error adding control to layout."); 1525 ui_label_destroy(progress->label); 1526 progress->label = NULL; 1527 goto error; 1528 } 1529 1530 /* Action line */ 1531 rc = ui_label_create(ui_res, "", 1532 &progress->action); 1533 if (rc != EOK) { 1534 sysinst_error(sysinst, "Error creating label."); 1535 goto error; 1536 } 1537 1538 if (ui_is_textmode(sysinst->ui)) { 1539 rect.p0.x = arect.p0.x; 1540 rect.p0.y = 3; 1541 rect.p1.x = arect.p1.x; 1542 rect.p1.y = 4; 1543 } else { 1544 rect.p0.x = arect.p0.x; 1545 rect.p0.y = 40; 1546 rect.p1.x = arect.p1.x; 1547 rect.p1.y = 60; 1548 } 1549 ui_label_set_rect(progress->action, &rect); 1550 ui_label_set_halign(progress->action, gfx_halign_center); 1551 ui_label_set_valign(progress->action, gfx_valign_top); 1552 1553 rc = ui_fixed_add(fixed, ui_label_ctl(progress->action)); 1554 if (rc != EOK) { 1555 sysinst_error(sysinst, "Error adding control to layout."); 1556 ui_label_destroy(progress->label); 1557 progress->label = NULL; 1558 goto error; 1559 } 1560 1561 /* Progress line */ 1562 rc = ui_label_create(ui_res, "", 1563 &progress->progress); 1564 if (rc != EOK) { 1565 sysinst_error(sysinst, "Error creating label."); 1566 goto error; 1567 } 1568 1569 if (ui_is_textmode(sysinst->ui)) { 1570 rect.p0.x = arect.p0.x; 1571 rect.p0.y = 5; 1572 rect.p1.x = arect.p1.x; 1573 rect.p1.y = arect.p1.y; 1574 } else { 1575 rect.p0.x = arect.p0.x; 1576 rect.p0.y = 70; 1577 rect.p1.x = arect.p1.x; 1578 rect.p1.y = arect.p1.y; 1579 } 1580 ui_label_set_rect(progress->progress, &rect); 1581 ui_label_set_halign(progress->progress, gfx_halign_center); 1582 ui_label_set_valign(progress->progress, gfx_valign_top); 1583 1584 rc = ui_fixed_add(fixed, ui_label_ctl(progress->progress)); 1585 if (rc != EOK) { 1586 sysinst_error(sysinst, "Error adding control to layout."); 1587 ui_label_destroy(progress->label); 1588 progress->label = NULL; 1589 goto error; 1590 } 1591 1592 ui_window_add(window, ui_fixed_ctl(fixed)); 1593 fixed = NULL; 1594 1595 rc = ui_window_paint(window); 1596 if (rc != EOK) { 1597 sysinst_error(sysinst, "Error painting window."); 1598 goto error; 1599 } 1600 1601 progress->window = window; 1602 progress->fixed = fixed; 1603 *rprogress = progress; 1604 return EOK; 1605 error: 1606 if (progress != NULL && progress->fixed != NULL) 1607 ui_fixed_destroy(progress->fixed); 1608 if (window != NULL) 1609 ui_window_destroy(window); 1610 if (progress != NULL) 1611 free(progress); 1612 return rc; 1613 } 1614 1615 /** Destroy installation progress window. 1616 * 1617 * @param sysinst System installer 1618 * @param rprogress Place to store pointer to new progress window 1619 * @return EOK on success or an error code 1620 */ 1621 static void sysinst_progress_destroy(sysinst_progress_t *progress) 1622 { 1623 if (progress == NULL) 1624 return; 1625 1626 ui_window_destroy(progress->window); 1627 free(progress); 1628 } 1629 1630 /** Set current progress message. 1631 * 1632 * @param sysinst System installer 1633 * @param progress Progress text 1634 */ 1635 static void sysinst_progress(sysinst_t *sysinst, const char *progress) 1636 { 1637 log_msg(LOG_DEFAULT, LVL_NOTE, "%s", progress); 1638 1639 if (sysinst->progress == NULL) 1640 return; 1641 1642 ui_label_set_text(sysinst->progress->progress, progress); 1643 ui_label_paint(sysinst->progress->progress); 1644 } 1645 1646 /** Set current action message. 1647 * 1648 * @param sysinst System installer 1649 * @param action Action text 1650 */ 1651 static void sysinst_action(sysinst_t *sysinst, const char *action) 1652 { 1653 log_msg(LOG_DEFAULT, LVL_NOTE, "%s", action); 1654 1655 if (sysinst->progress == NULL) 1656 return; 1657 1658 ui_label_set_text(sysinst->progress->action, action); 1659 ui_label_paint(sysinst->progress->action); 1660 } 1661 1662 /** Set current error message. 1663 * 1664 * @param sysinst System installer 1665 * @param errmsg Error message 1666 */ 1667 static void sysinst_error(sysinst_t *sysinst, const char *errmsg) 1668 { 1669 str_cpy(sysinst->errmsg, sizeof(sysinst->errmsg), errmsg); 1670 log_msg(LOG_DEFAULT, LVL_ERROR, errmsg); 1671 } 1672 1673 /** Log a debug message. 1674 * 1675 * @param sysinst System installer 1676 * @param errmsg Error message 1677 */ 1678 static void sysinst_debug(sysinst_t *sysinst, const char *msg) 1679 { 1680 log_msg(LOG_DEFAULT, LVL_ERROR, msg); 1681 } 1682 1683 /** Start system installation. 1684 * 1685 * @param sysinst System installer 1686 * @return EOK on success or an error code 1687 */ 1688 static int sysinst_start(sysinst_t *sysinst) 1689 { 1690 errno_t rc; 1691 fid_t fid; 1692 1693 rc = sysinst_progress_create(sysinst, &sysinst->progress); 1694 if (rc != EOK) 1695 return rc; 1696 1697 fid = fibril_create(sysinst_install_fibril, (void *)sysinst); 1698 if (fid == 0) { 1699 sysinst_error(sysinst, "Out of memory."); 1700 return ENOMEM; 1701 } 1702 1703 fibril_add_ready(fid); 1704 return EOK; 1705 } 1706 1707 /** Create installation confirmation dialog. 1708 * 1709 * @param sysinst System installer 1710 * @return EOK on success or an error code 1711 */ 1712 static errno_t sysinst_confirm_create(sysinst_t *sysinst) 1713 { 1714 ui_msg_dialog_params_t params; 1715 ui_msg_dialog_t *dialog; 1716 errno_t rc; 1717 1718 ui_msg_dialog_params_init(¶ms); 1719 params.caption = "System installation"; 1720 params.text = "This will install HelenOS to your computer. Continue?"; 1721 params.choice = umdc_ok_cancel; 1722 params.flags |= umdf_topmost | umdf_center; 1723 1724 rc = ui_msg_dialog_create(sysinst->ui, ¶ms, &dialog); 1725 if (rc != EOK) 1726 return rc; 1727 1728 ui_msg_dialog_set_cb(dialog, &sysinst_confirm_cb, sysinst); 1729 return EOK; 1730 } 1731 1732 /** Create upgrade confirmation dialog. 1733 * 1734 * @param sysinst System installer 1735 * @return EOK on success or an error code 1736 */ 1737 static errno_t sysinst_upgrade_confirm_create(sysinst_t *sysinst) 1738 { 1739 ui_msg_dialog_params_t params; 1740 ui_msg_dialog_t *dialog; 1741 errno_t rc; 1742 1743 ui_msg_dialog_params_init(¶ms); 1744 params.caption = "System upgrade"; 1745 params.text = "Existing installation found. " 1746 "Do you want to upgrade it?"; 1747 params.choice = umdc_ok_cancel; 1748 params.flags |= umdf_topmost | umdf_center; 1749 1750 rc = ui_msg_dialog_create(sysinst->ui, ¶ms, &dialog); 1751 if (rc != EOK) 1752 return rc; 1753 1754 ui_msg_dialog_set_cb(dialog, &sysinst_upgrade_confirm_cb, sysinst); 1755 return EOK; 1756 } 1757 1758 /** Create restart dialog. 1759 * 1760 * @param sysinst System installer 1761 * @return EOK on success or an error code 1762 */ 1763 static errno_t sysinst_restart_dlg_create(sysinst_t *sysinst) 1764 { 1765 ui_msg_dialog_params_t params; 1766 ui_msg_dialog_t *dialog; 1767 errno_t rc; 1768 1769 ui_msg_dialog_params_init(¶ms); 1770 params.caption = "Restart System"; 1771 1772 if (sysinst->oper == sio_install) 1773 params.text = "Installation complete. Restart the system?"; 1774 else 1775 params.text = "Upgrade complete. Restart the system?"; 1776 1777 params.choice = umdc_ok_cancel; 1778 params.flags |= umdf_topmost | umdf_center; 1779 1780 rc = ui_msg_dialog_create(sysinst->ui, ¶ms, &dialog); 1781 if (rc != EOK) 1782 return rc; 1783 1784 ui_msg_dialog_set_cb(dialog, &sysinst_restart_dlg_cb, sysinst); 1785 return EOK; 1786 } 1787 1788 /** Run system installer on display. 1789 * 1790 * @param display_spec Display specification 1791 * @return EOK on success or an error code 1792 */ 1793 static errno_t sysinst_run(const char *display_spec) 1794 { 1795 ui_t *ui = NULL; 1796 sysinst_t *sysinst; 1797 ui_wnd_params_t params; 1798 errno_t rc; 1799 1800 sysinst = calloc(1, sizeof(sysinst_t)); 1801 if (sysinst == NULL) 1802 return ENOMEM; 1803 1804 fibril_condvar_initialize(&sysinst->responded_cv); 1805 fibril_mutex_initialize(&sysinst->responded_lock); 1806 1807 rc = fmgt_create(&sysinst->fmgt); 1808 if (rc != EOK) { 1809 printf("Out of memory.\n"); 1810 goto error; 1811 } 1812 1813 fmgt_set_cb(sysinst->fmgt, &sysinst_fmgt_cb, (void *)sysinst); 1814 fmgt_set_init_update(sysinst->fmgt, true); 1815 1816 rc = ui_create(display_spec, &ui); 1817 if (rc != EOK) { 1818 printf("Error creating UI on display %s.\n", display_spec); 1819 goto error; 1820 } 1821 1822 sysinst->ui = ui; 1823 1824 ui_wnd_params_init(¶ms); 1825 params.caption = "System Installation"; 1826 params.style &= ~ui_wds_decorated; 1827 params.placement = ui_wnd_place_full_screen; 1828 params.flags |= ui_wndf_topmost | ui_wndf_nofocus; 1829 1830 rc = ui_window_create(sysinst->ui, ¶ms, &sysinst->bgwindow); 1831 if (rc != EOK) { 1832 printf("Error creating window.\n"); 1833 goto error; 1834 } 1835 1836 ui_window_set_cb(sysinst->bgwindow, &bg_window_cb, (void *)sysinst); 1837 1838 if (ui_is_textmode(sysinst->ui)) { 1839 rc = gfx_color_new_ega(0x17, &sysinst->bg_color); 1840 if (rc != EOK) { 1841 printf("Error allocating color.\n"); 1842 goto error; 1843 } 1844 } else { 1845 rc = gfx_color_new_rgb_i16(0x8000, 0xc800, 0xffff, &sysinst->bg_color); 1846 if (rc != EOK) { 1847 printf("Error allocating color.\n"); 1848 goto error; 1849 } 1850 } 1851 1852 rc = ui_window_paint(sysinst->bgwindow); 1853 if (rc != EOK) { 1854 printf("Error painting window.\n"); 1855 goto error; 1856 } 1857 1858 rc = sysinst_confirm_create(sysinst); 1859 if (rc != EOK) { 1860 printf("Error creating window.\n"); 1861 goto error; 1862 } 1863 1864 ui_run(ui); 1865 1866 if (sysinst->bgwindow != NULL) 1867 ui_window_destroy(sysinst->bgwindow); 1868 if (sysinst->system != NULL) 1869 system_close(sysinst->system); 1870 gfx_color_delete(sysinst->bg_color); 1871 ui_destroy(ui); 1872 free(sysinst); 1873 return EOK; 1874 error: 1875 if (sysinst->fmgt != NULL) 1876 fmgt_destroy(sysinst->fmgt); 1877 if (sysinst->system != NULL) 1878 system_close(sysinst->system); 1879 if (sysinst->bg_color != NULL) 1880 gfx_color_delete(sysinst->bg_color); 1881 if (sysinst->bgwindow != NULL) 1882 ui_window_destroy(sysinst->bgwindow); 1883 if (ui != NULL) 1884 ui_destroy(ui); 1885 free(sysinst); 1886 return rc; 1887 } 1888 1889 static void print_syntax(void) 1890 { 1891 printf("Syntax: " NAME " [-d <display-spec>]\n"); 1892 } 1893 1894 int main(int argc, char *argv[]) 1895 { 1896 const char *display_spec = UI_ANY_DEFAULT; 1897 errno_t rc; 1898 int i; 1899 1900 i = 1; 1901 while (i < argc && argv[i][0] == '-') { 1902 if (str_cmp(argv[i], "-d") == 0) { 1903 ++i; 1904 if (i >= argc) { 1905 printf("Argument missing.\n"); 1906 print_syntax(); 1907 return 1; 1908 } 1909 1910 display_spec = argv[i++]; 1911 } else { 1912 printf("Invalid option '%s'.\n", argv[i]); 1913 print_syntax(); 1914 return 1; 1915 } 1916 } 1917 1918 if (i < argc) { 1919 print_syntax(); 530 printf("Cannot determine installation device.\n"); 1920 531 return 1; 1921 532 } 1922 533 1923 if (log_init(NAME) != EOK) { 1924 printf(NAME ": Failed to initialize logging.\n"); 1925 return 1; 1926 } 1927 1928 rc = sysinst_run(display_spec); 1929 if (rc != EOK) 1930 return 1; 1931 1932 return 0; 534 return sysinst_install(default_devs[i]); 1933 535 } 1934 536
Note:
See TracChangeset
for help on using the changeset viewer.
