Changes in uspace/app/sysinst/sysinst.c [c24b0dcb:629b480] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/sysinst/sysinst.c
rc24b0dcb r629b480 1 1 /* 2 * Copyright (c) 20 18Jiri Svoboda2 * Copyright (c) 2025 Jiri Svoboda 3 3 * All rights reserved. 4 4 * … … 41 41 #include <errno.h> 42 42 #include <fdisk.h> 43 #include <futil.h> 44 #include <gfx/render.h> 45 #include <io/log.h> 43 46 #include <loc.h> 44 47 #include <stdio.h> … … 46 49 #include <str.h> 47 50 #include <str_error.h> 51 #include <system.h> 52 #include <ui/msgdialog.h> 53 #include <ui/ui.h> 54 #include <ui/window.h> 48 55 #include <vfs/vfs.h> 49 56 #include <vol.h> 50 57 51 #include "futil.h"52 58 #include "grub.h" 53 59 #include "rdimg.h" 54 60 #include "volume.h" 61 #include "sysinst.h" 62 63 #define NAME "sysinst" 55 64 56 65 /** Device to install to … … 62 71 * in Grub notation). 63 72 */ 64 #define DEFAULT_DEV "devices/\\hw\\sys\\00:01.0\\ata-c1\\d0" 73 #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 76 //#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.2\\uhci_rh\\usb01_a1\\mass-storage0\\l0" 66 77 /** Volume label for the new file system */ … … 79 90 #define BOOT_BLOCK_IDX 0 /* MBR */ 80 91 92 #define CFG_FILES_SRC "/cfg" 93 #define CFG_FILES_DEST MOUNT_POINT "/cfg" 94 95 static const char *default_devs[] = { 96 DEFAULT_DEV_0, 97 DEFAULT_DEV_1, 98 DEFAULT_DEV_2, 99 NULL 100 }; 101 81 102 static const char *sys_dirs[] = { 82 103 "/cfg", 83 "/data" 104 "/data", 105 NULL 84 106 }; 85 107 86 /** Label the destination device. 87 * 108 static fibril_mutex_t shutdown_lock; 109 static fibril_condvar_t shutdown_cv; 110 static bool shutdown_stopped; 111 static bool shutdown_failed; 112 113 static void sysinst_shutdown_complete(void *); 114 static void sysinst_shutdown_failed(void *); 115 116 static system_cb_t sysinst_system_cb = { 117 .shutdown_complete = sysinst_shutdown_complete, 118 .shutdown_failed = sysinst_shutdown_failed 119 }; 120 121 static void wnd_close(ui_window_t *, void *); 122 static errno_t bg_wnd_paint(ui_window_t *, void *); 123 124 static ui_window_cb_t bg_window_cb = { 125 .close = wnd_close, 126 .paint = bg_wnd_paint 127 }; 128 129 static ui_window_cb_t progress_window_cb = { 130 .close = wnd_close 131 }; 132 133 static void sysinst_confirm_button(ui_msg_dialog_t *, void *, unsigned); 134 static void sysinst_confirm_close(ui_msg_dialog_t *, void *); 135 136 static ui_msg_dialog_cb_t sysinst_confirm_cb = { 137 .button = sysinst_confirm_button, 138 .close = sysinst_confirm_close 139 }; 140 141 static errno_t sysinst_restart_dlg_create(sysinst_t *); 142 static void sysinst_restart_dlg_button(ui_msg_dialog_t *, void *, unsigned); 143 static void sysinst_restart_dlg_close(ui_msg_dialog_t *, void *); 144 145 static ui_msg_dialog_cb_t sysinst_restart_dlg_cb = { 146 .button = sysinst_restart_dlg_button, 147 .close = sysinst_restart_dlg_close 148 }; 149 150 static int sysinst_start(sysinst_t *); 151 static errno_t sysinst_restart(sysinst_t *); 152 static void sysinst_progress_destroy(sysinst_progress_t *); 153 static void sysinst_action(sysinst_t *, const char *); 154 static void sysinst_error(sysinst_t *, const char *); 155 static void sysinst_debug(sysinst_t *, const char *); 156 157 static void sysinst_futil_copy_file(void *, const char *, const char *); 158 static void sysinst_futil_create_dir(void *, const char *); 159 static errno_t sysinst_eject_dev(sysinst_t *, service_id_t); 160 161 static futil_cb_t sysinst_futil_cb = { 162 .copy_file = sysinst_futil_copy_file, 163 .create_dir = sysinst_futil_create_dir 164 }; 165 166 static void sysinst_error_msg_button(ui_msg_dialog_t *, void *, unsigned); 167 static void sysinst_error_msg_close(ui_msg_dialog_t *, void *); 168 169 static ui_msg_dialog_cb_t sysinst_error_msg_cb = { 170 .button = sysinst_error_msg_button, 171 .close = sysinst_error_msg_close 172 }; 173 174 /** Close window. 175 * 176 * @param window Window 177 * @param arg Argument (sysinst_t *) 178 */ 179 static void wnd_close(ui_window_t *window, void *arg) 180 { 181 (void)window; 182 (void)arg; 183 } 184 185 /** Paint background window. 186 * 187 * @param window Window 188 * @param arg Argument (sysinst_t *) 189 */ 190 static errno_t bg_wnd_paint(ui_window_t *window, void *arg) 191 { 192 sysinst_t *sysinst = (sysinst_t *)arg; 193 gfx_rect_t app_rect; 194 gfx_context_t *gc; 195 errno_t rc; 196 197 gc = ui_window_get_gc(window); 198 199 rc = gfx_set_color(gc, sysinst->bg_color); 200 if (rc != EOK) 201 return rc; 202 203 ui_window_get_app_rect(window, &app_rect); 204 205 rc = gfx_fill_rect(gc, &app_rect); 206 if (rc != EOK) 207 return rc; 208 209 rc = gfx_update(gc); 210 if (rc != EOK) 211 return rc; 212 213 return EOK; 214 } 215 216 /** Installation confirm dialog OK button press. 217 * 218 * @param dialog Message dialog 219 * @param arg Argument (sysinst_t *) 220 * @param btn Button number 221 * @param earg Entry argument 222 */ 223 static void sysinst_confirm_button(ui_msg_dialog_t *dialog, void *arg, 224 unsigned btn) 225 { 226 sysinst_t *sysinst = (sysinst_t *) arg; 227 228 ui_msg_dialog_destroy(dialog); 229 230 switch (btn) { 231 case 0: 232 /* OK */ 233 sysinst_start(sysinst); 234 break; 235 default: 236 /* Cancel */ 237 ui_quit(sysinst->ui); 238 break; 239 } 240 } 241 242 /** Installation confirm dialog close request. 243 * 244 * @param dialog Message dialog 245 * @param arg Argument (sysinst_t *) 246 */ 247 static void sysinst_confirm_close(ui_msg_dialog_t *dialog, void *arg) 248 { 249 sysinst_t *sysinst = (sysinst_t *) arg; 250 251 ui_msg_dialog_destroy(dialog); 252 ui_quit(sysinst->ui); 253 } 254 255 /** Restart system dialog OK button press. 256 * 257 * @param dialog Message dialog 258 * @param arg Argument (sysinst_t *) 259 * @param btn Button number 260 * @param earg Entry argument 261 */ 262 static void sysinst_restart_dlg_button(ui_msg_dialog_t *dialog, void *arg, 263 unsigned btn) 264 { 265 sysinst_t *sysinst = (sysinst_t *) arg; 266 267 ui_msg_dialog_destroy(dialog); 268 269 (void)sysinst; 270 271 switch (btn) { 272 case 0: 273 /* OK */ 274 (void)sysinst_restart(sysinst); 275 break; 276 default: 277 /* Cancel */ 278 ui_quit(sysinst->ui); 279 break; 280 } 281 } 282 283 /** Restat system dialog close request. 284 * 285 * @param dialog Message dialog 286 * @param arg Argument (sysinst_t *) 287 */ 288 static void sysinst_restart_dlg_close(ui_msg_dialog_t *dialog, void *arg) 289 { 290 sysinst_t *sysinst = (sysinst_t *) arg; 291 292 ui_msg_dialog_destroy(dialog); 293 ui_quit(sysinst->ui); 294 } 295 296 /** Installation error message dialog button press. 297 * 298 * @param dialog Message dialog 299 * @param arg Argument (sysinst_t *) 300 * @param bnum Button number 301 */ 302 static void sysinst_error_msg_button(ui_msg_dialog_t *dialog, 303 void *arg, unsigned bnum) 304 { 305 sysinst_t *sysinst = (sysinst_t *) arg; 306 307 ui_msg_dialog_destroy(dialog); 308 ui_quit(sysinst->ui); 309 } 310 311 /** Installation error message dialog close request. 312 * 313 * @param dialog Message dialog 314 * @param arg Argument (shutdown_dlg_t *) 315 */ 316 static void sysinst_error_msg_close(ui_msg_dialog_t *dialog, void *arg) 317 { 318 sysinst_t *sysinst = (sysinst_t *) arg; 319 320 ui_msg_dialog_destroy(dialog); 321 ui_quit(sysinst->ui); 322 } 323 324 /** Create error message dialog. 325 * 326 * @param sysinst System installer 327 * @return EOK on success or an error code 328 */ 329 static errno_t sysinst_error_msg_create(sysinst_t *sysinst) 330 { 331 ui_msg_dialog_params_t params; 332 ui_msg_dialog_t *dialog; 333 errno_t rc; 334 335 ui_msg_dialog_params_init(¶ms); 336 params.caption = "Error"; 337 params.text = sysinst->errmsg; 338 params.flags |= umdf_topmost | umdf_center; 339 340 rc = ui_msg_dialog_create(sysinst->ui, ¶ms, &dialog); 341 if (rc != EOK) 342 return rc; 343 344 ui_msg_dialog_set_cb(dialog, &sysinst_error_msg_cb, (void *)sysinst); 345 346 return EOK; 347 } 348 349 /** Called when futil is starting to copy a file. 350 * 351 * @param arg Argument (sysinst_t *) 352 * @param src Source path 353 * @param dest Destination path 354 */ 355 static void sysinst_futil_copy_file(void *arg, const char *src, 356 const char *dest) 357 { 358 sysinst_t *sysinst = (sysinst_t *)arg; 359 char buf[128]; 360 361 (void)src; 362 snprintf(buf, sizeof(buf), "Copying %s.", dest); 363 sysinst_action(sysinst, buf); 364 } 365 366 /** Called when futil is about to create a directory. 367 * 368 * @param arg Argument (sysinst_t *) 369 * @param dest Destination path 370 */ 371 static void sysinst_futil_create_dir(void *arg, const char *dest) 372 { 373 sysinst_t *sysinst = (sysinst_t *)arg; 374 char buf[128]; 375 376 snprintf(buf, sizeof(buf), "Creating %s.", dest); 377 sysinst_action(sysinst, buf); 378 } 379 380 /** System shutdown complete. 381 * 382 * @param arg Argument (shutdown_t *) 383 */ 384 static void sysinst_shutdown_complete(void *arg) 385 { 386 (void)arg; 387 388 fibril_mutex_lock(&shutdown_lock); 389 shutdown_stopped = true; 390 shutdown_failed = false; 391 fibril_condvar_broadcast(&shutdown_cv); 392 fibril_mutex_unlock(&shutdown_lock); 393 } 394 395 /** System shutdown failed. 396 * 397 * @param arg Argument (not used) 398 */ 399 static void sysinst_shutdown_failed(void *arg) 400 { 401 (void)arg; 402 403 fibril_mutex_lock(&shutdown_lock); 404 shutdown_stopped = true; 405 shutdown_failed = true; 406 fibril_condvar_broadcast(&shutdown_cv); 407 fibril_mutex_unlock(&shutdown_lock); 408 } 409 410 /** Check the if the destination device exists. 411 * 412 * @param dev Disk device 413 * 414 * @return EOK on success or an error code 415 */ 416 static errno_t sysinst_check_dev(const char *dev) 417 { 418 service_id_t sid; 419 errno_t rc; 420 421 rc = loc_service_get_id(dev, &sid, 0); 422 if (rc != EOK) 423 return rc; 424 425 (void)sid; 426 return EOK; 427 } 428 429 /** Label and mount the destination device. 430 * 431 * @param sysinst System installer 88 432 * @param dev Disk device to label 89 433 * @param psvc_id Place to store service ID of the created partition … … 91 435 * @return EOK on success or an error code 92 436 */ 93 static errno_t sysinst_label_dev( const char *dev, service_id_t *psvc_id)94 { 95 fdisk_t *fdisk ;96 fdisk_dev_t *fdev ;437 static errno_t sysinst_label_dev(sysinst_t *sysinst, const char *dev) 438 { 439 fdisk_t *fdisk = NULL; 440 fdisk_dev_t *fdev = NULL; 97 441 fdisk_part_t *part; 98 442 fdisk_part_spec_t pspec; 99 443 fdisk_part_info_t pinfo; 444 bool dir_created = false; 445 bool label_created = false; 100 446 capa_spec_t capa; 101 447 service_id_t sid; 102 448 errno_t rc; 103 449 104 printf("sysinst_label_dev(): get service ID '%s'\n", dev); 450 sysinst_debug(sysinst, "sysinst_label_dev(): get service ID"); 451 105 452 rc = loc_service_get_id(dev, &sid, 0); 106 453 if (rc != EOK) 107 return rc;108 109 printf("sysinst_label_dev(): open device\n");454 goto error; 455 456 sysinst_debug(sysinst, "sysinst_label_dev(): open device"); 110 457 111 458 rc = fdisk_create(&fdisk); 112 459 if (rc != EOK) { 113 printf("Error initializing fdisk.\n");114 return rc;460 sysinst_error(sysinst, "Error initializing fdisk."); 461 goto error; 115 462 } 116 463 117 464 rc = fdisk_dev_open(fdisk, sid, &fdev); 118 465 if (rc != EOK) { 119 printf("Error opening device.\n");120 return rc;121 } 122 123 printf("sysinst_label_dev(): create mount directory\n");466 sysinst_error(sysinst, "Error opening device."); 467 goto error; 468 } 469 470 sysinst_debug(sysinst, "sysinst_label_dev(): create mount directory"); 124 471 125 472 rc = vfs_link_path(MOUNT_POINT, KIND_DIRECTORY, NULL); 126 if (rc != EOK) 127 return rc; 128 129 printf("sysinst_label_dev(): create label\n"); 473 if (rc != EOK) { 474 sysinst_error(sysinst, "Error creating mount directory."); 475 goto error; 476 } 477 478 dir_created = true; 479 480 sysinst_debug(sysinst, "sysinst_label_dev(): create label"); 130 481 131 482 rc = fdisk_label_create(fdev, lt_mbr); 132 483 if (rc != EOK) { 133 printf("Error creating label: %s.\n", str_error(rc)); 134 return rc; 135 } 136 137 printf("sysinst_label_dev(): create partition\n"); 484 sysinst_error(sysinst, "Error creating label."); 485 goto error; 486 } 487 488 label_created = true; 489 490 sysinst_debug(sysinst, "sysinst_label_dev(): create partition"); 138 491 139 492 rc = fdisk_part_get_max_avail(fdev, spc_pri, &capa); 140 493 if (rc != EOK) { 141 printf("Error getting available capacity: %s.\n", str_error(rc)); 142 return rc; 494 sysinst_error(sysinst, 495 "Error getting available capacity."); 496 goto error; 143 497 } 144 498 … … 152 506 rc = fdisk_part_create(fdev, &pspec, &part); 153 507 if (rc != EOK) { 154 printf("Error creating partition.\n");155 return rc;508 sysinst_error(sysinst, "Error creating partition."); 509 goto error; 156 510 } 157 511 158 512 rc = fdisk_part_get_info(part, &pinfo); 159 513 if (rc != EOK) { 160 printf("Error getting partition information.\n"); 161 return rc; 162 } 163 164 printf("sysinst_label_dev(): OK\n"); 165 *psvc_id = pinfo.svc_id; 514 sysinst_error(sysinst, "Error getting partition information."); 515 goto error; 516 } 517 518 sysinst_debug(sysinst, "sysinst_label_dev(): OK"); 519 fdisk_dev_close(fdev); 520 fdisk_destroy(fdisk); 521 sysinst->psvc_id = pinfo.svc_id; 522 return EOK; 523 error: 524 if (label_created) 525 fdisk_label_destroy(fdev); 526 if (dir_created) 527 (void)vfs_unlink_path(MOUNT_POINT); 528 if (fdev != NULL) 529 fdisk_dev_close(fdev); 530 if (fdisk != NULL) 531 fdisk_destroy(fdisk); 532 return rc; 533 } 534 535 /** Finish/unmount destination device. 536 * 537 * @param sysinst System installer 538 * 539 * @return EOK on success or an error code 540 */ 541 static errno_t sysinst_finish_dev(sysinst_t *sysinst) 542 { 543 errno_t rc; 544 545 sysinst_debug(sysinst, "sysinst_finish_dev(): eject target volume"); 546 rc = sysinst_eject_dev(sysinst, sysinst->psvc_id); 547 if (rc != EOK) 548 return rc; 549 550 sysinst_debug(sysinst, "sysinst_finish_dev(): " 551 "deleting mount directory"); 552 (void)vfs_unlink_path(MOUNT_POINT); 553 166 554 return EOK; 167 555 } … … 169 557 /** Set up system volume structure. 170 558 * 171 * @return EOK on success or an error code 172 */ 173 static errno_t sysinst_setup_sysvol(void) 559 * @param sysinst System installer 560 * @return EOK on success or an error code 561 */ 562 static errno_t sysinst_setup_sysvol(sysinst_t *sysinst) 174 563 { 175 564 errno_t rc; … … 188 577 rc = vfs_link_path(path, KIND_DIRECTORY, NULL); 189 578 if (rc != EOK) { 190 printf("Error creating directory '%s'.\n", path);579 sysinst_error(sysinst, "Error creating directory."); 191 580 goto error; 192 581 } … … 199 588 free(path); 200 589 path = NULL; 590 591 /* Copy initial configuration files */ 592 rc = futil_rcopy_contents(sysinst->futil, CFG_FILES_SRC, 593 CFG_FILES_DEST); 594 if (rc != EOK) 595 return rc; 201 596 202 597 return EOK; … … 211 606 * @return EOK on success or an error code 212 607 */ 213 static errno_t sysinst_copy_boot_files(void) 214 { 215 errno_t rc; 216 217 printf("sysinst_copy_boot_files(): copy bootloader files\n"); 218 rc = futil_rcopy_contents(BOOT_FILES_SRC, MOUNT_POINT); 219 if (rc != EOK) 220 return rc; 221 222 printf("sysinst_copy_boot_files(): OK\n"); 608 static errno_t sysinst_copy_boot_files(sysinst_t *sysinst) 609 { 610 errno_t rc; 611 612 log_msg(LOG_DEFAULT, LVL_NOTE, 613 "sysinst_copy_boot_files(): copy bootloader files"); 614 rc = futil_rcopy_contents(sysinst->futil, BOOT_FILES_SRC, MOUNT_POINT); 615 if (rc != EOK) 616 return rc; 617 618 sysinst_debug(sysinst, "sysinst_copy_boot_files(): OK"); 223 619 return EOK; 224 620 } … … 226 622 /** Set up configuration in the initial RAM disk. 227 623 * 228 * @return EOK on success or an error code 229 */ 230 static errno_t sysinst_customize_initrd(void) 624 * @param sysinst System installer 625 * @return EOK on success or an error code 626 */ 627 static errno_t sysinst_customize_initrd(sysinst_t *sysinst) 231 628 { 232 629 errno_t rc; … … 240 637 rc = rd_img_open(MOUNT_POINT "/boot/initrd.img", &rdpath, &rd); 241 638 if (rc != EOK) { 242 printf("Error opening initial RAM disk image.\n");243 goto error; 244 } 245 246 rv = asprintf(&path, "%s%s", rdpath, "/cfg/ volsrv.sif");639 sysinst_error(sysinst, "Error opening initial RAM disk image."); 640 goto error; 641 } 642 643 rv = asprintf(&path, "%s%s", rdpath, "/cfg/initvol.sif"); 247 644 if (rv < 0) { 248 645 rc = ENOMEM; … … 250 647 } 251 648 252 printf("Configuring volume server.\n"); 649 sysinst_debug(sysinst, "Configuring volume server."); 650 253 651 rc = vol_volumes_create(path, &volumes); 254 652 if (rc != EOK) { 255 printf("Error creating volume server configuration.\n"); 653 sysinst_error(sysinst, 654 "Error creating volume server configuration."); 256 655 rc = EIO; 257 656 goto error; 258 657 } 259 658 260 printf("Configuring volume server: look up volume\n");659 sysinst_debug(sysinst, "Configuring volume server: look up volume"); 261 660 rc = vol_volume_lookup_ref(volumes, INST_VOL_LABEL, &volume); 262 661 if (rc != EOK) { 263 printf("Error creating volume server configuration.\n"); 662 sysinst_error(sysinst, 663 "Error creating volume server configuration."); 264 664 rc = EIO; 265 665 goto error; 266 666 } 267 667 268 printf("Configuring volume server: set mount point\n");668 sysinst_debug(sysinst, "Configuring volume server: set mount point"); 269 669 rc = vol_volume_set_mountp(volume, INST_VOL_MP); 270 670 if (rc != EOK) { 271 printf("Error creating system partition configuration.\n"); 671 sysinst_error(sysinst, 672 "Error creating system partition configuration."); 272 673 rc = EIO; 273 674 goto error; 274 675 } 275 676 276 printf("Configuring volume server: delete reference\n"); 677 rc = vol_volumes_sync(volumes); 678 if (rc != EOK) { 679 sysinst_error(sysinst, "Error saving volume confiuration."); 680 goto error; 681 } 682 683 log_msg(LOG_DEFAULT, LVL_NOTE, 684 "Configuring volume server: delete reference"); 277 685 vol_volume_del_ref(volume); 278 686 volume = NULL; 279 printf("Configuring volume server: destroy volumes object\n"); 687 log_msg(LOG_DEFAULT, LVL_NOTE, 688 "Configuring volume server: destroy volumes object"); 280 689 vol_volumes_destroy(volumes); 281 690 volumes = NULL; … … 283 692 rc = rd_img_close(rd); 284 693 if (rc != EOK) { 285 printf("Error closing initial RAM disk image.\n");694 sysinst_error(sysinst, "Error closing initial RAM disk image."); 286 695 rc = EIO; 287 696 goto error; … … 326 735 * Install Grub's boot blocks. 327 736 * 737 * @param sysinst System installer 328 738 * @param devp Disk device 329 739 * @return EOK on success or an error code 330 740 */ 331 static errno_t sysinst_copy_boot_blocks( const char *devp)741 static errno_t sysinst_copy_boot_blocks(sysinst_t *sysinst, const char *devp) 332 742 { 333 743 void *boot_img; … … 343 753 errno_t rc; 344 754 345 printf("sysinst_copy_boot_blocks: Read boot block image.\n"); 346 rc = futil_get_file(BOOT_FILES_SRC "/boot/grub/i386-pc/boot.img", 755 log_msg(LOG_DEFAULT, LVL_NOTE, 756 "sysinst_copy_boot_blocks: Read boot block image."); 757 758 rc = futil_get_file(sysinst->futil, 759 BOOT_FILES_SRC "/boot/grub/i386-pc/boot.img", 347 760 &boot_img, &boot_img_size); 348 761 if (rc != EOK || boot_img_size != 512) 349 762 return EIO; 350 763 351 printf("sysinst_copy_boot_blocks: Read GRUB core image.\n"); 352 rc = futil_get_file(BOOT_FILES_SRC "/boot/grub/i386-pc/core.img", 764 log_msg(LOG_DEFAULT, LVL_NOTE, 765 "sysinst_copy_boot_blocks: Read GRUB core image."); 766 767 rc = futil_get_file(sysinst->futil, 768 BOOT_FILES_SRC "/boot/grub/i386-pc/core.img", 353 769 &core_img, &core_img_size); 354 770 if (rc != EOK) 355 771 return EIO; 356 772 357 printf("sysinst_copy_boot_blocks: get service ID.\n"); 773 log_msg(LOG_DEFAULT, LVL_NOTE, 774 "sysinst_copy_boot_blocks: get service ID."); 775 358 776 rc = loc_service_get_id(devp, &sid, 0); 359 777 if (rc != EOK) 360 778 return rc; 361 779 362 printf("sysinst_copy_boot_blocks: block_init.\n"); 363 rc = block_init(sid, 512); 364 if (rc != EOK) 365 return rc; 366 367 printf("sysinst_copy_boot_blocks: get block size\n"); 780 log_msg(LOG_DEFAULT, LVL_NOTE, 781 "sysinst_copy_boot_blocks: block_init."); 782 783 rc = block_init(sid); 784 if (rc != EOK) 785 return rc; 786 787 log_msg(LOG_DEFAULT, LVL_NOTE, 788 "sysinst_copy_boot_blocks: get block size"); 789 368 790 rc = block_get_bsize(sid, &bsize); 369 791 if (rc != EOK) … … 371 793 372 794 if (bsize != 512) { 373 printf("Device block size != 512.\n");795 sysinst_error(sysinst, "Device block size != 512."); 374 796 return EIO; 375 797 } 376 798 377 printf("sysinst_copy_boot_blocks: read boot block\n"); 799 log_msg(LOG_DEFAULT, LVL_NOTE, 800 "sysinst_copy_boot_blocks: read boot block"); 801 378 802 rc = block_read_direct(sid, BOOT_BLOCK_IDX, 1, bbuf); 379 803 if (rc != EOK) … … 390 814 --bl; 391 815 if ((void *)bl < core_img) { 392 printf("No block terminator in core image.\n"); 816 sysinst_error(sysinst, 817 "No block terminator in core image."); 393 818 return EIO; 394 819 } … … 404 829 set_unaligned_u64le(bbuf + grub_boot_machine_kernel_sector, core_start); 405 830 406 printf("sysinst_copy_boot_blocks: write boot block\n"); 831 log_msg(LOG_DEFAULT, LVL_NOTE, 832 "sysinst_copy_boot_blocks: write boot block"); 833 407 834 rc = block_write_direct(sid, BOOT_BLOCK_IDX, 1, bbuf); 408 835 if (rc != EOK) 409 836 return EIO; 410 837 411 printf("sysinst_copy_boot_blocks: write core blocks\n"); 838 log_msg(LOG_DEFAULT, LVL_NOTE, 839 "sysinst_copy_boot_blocks: write core blocks"); 840 412 841 /* XXX Must pad last block with zeros */ 413 842 rc = block_write_direct(sid, core_start, core_blocks, core_img); … … 415 844 return EIO; 416 845 417 printf("sysinst_copy_boot_blocks: OK.\n"); 846 log_msg(LOG_DEFAULT, LVL_NOTE, 847 "sysinst_copy_boot_blocks: OK."); 848 418 849 return EOK; 419 850 } … … 421 852 /** Eject installation volume. 422 853 * 423 * @param psvc_id Partition service ID 424 */ 425 static errno_t sysinst_eject_dev(service_id_t part_id) 854 * @param sysinst System installer 855 * @param part_id Partition service ID 856 * @return EOK on success or an error code 857 */ 858 static errno_t sysinst_eject_dev(sysinst_t *sysinst, service_id_t part_id) 426 859 { 427 860 vol_t *vol = NULL; … … 430 863 rc = vol_create(&vol); 431 864 if (rc != EOK) { 432 printf("Error contacting volume service.\n");865 sysinst_error(sysinst, "Error contacting volume service."); 433 866 goto out; 434 867 } 435 868 436 rc = vol_part_eject(vol, part_id );437 if (rc != EOK) { 438 printf("Error ejecting volume.\n");869 rc = vol_part_eject(vol, part_id, vef_none); 870 if (rc != EOK) { 871 sysinst_error(sysinst, "Error ejecting volume."); 439 872 goto out; 440 873 } … … 446 879 } 447 880 881 /** Physically eject volume by mount point. 882 * 883 * @param sysinst System installer 884 * @param path Mount point 885 * @return EOK on success or an error code 886 */ 887 static errno_t sysinst_eject_phys_by_mp(sysinst_t *sysinst, const char *path) 888 { 889 vol_t *vol = NULL; 890 sysarg_t part_id; 891 errno_t rc; 892 893 rc = vol_create(&vol); 894 if (rc != EOK) { 895 sysinst_error(sysinst, "Error contacting volume service."); 896 goto out; 897 } 898 899 log_msg(LOG_DEFAULT, LVL_NOTE, "vol_part_by_mp: mp='%s'\n", 900 path); 901 rc = vol_part_by_mp(vol, path, &part_id); 902 if (rc != EOK) { 903 sysinst_error(sysinst, 904 "Error finding installation media mount point."); 905 goto out; 906 } 907 908 log_msg(LOG_DEFAULT, LVL_NOTE, "eject svc_id %lu", (unsigned long)part_id); 909 rc = vol_part_eject(vol, part_id, vef_physical); 910 if (rc != EOK) { 911 sysinst_error(sysinst, "Error ejecting volume."); 912 goto out; 913 } 914 915 rc = EOK; 916 out: 917 vol_destroy(vol); 918 return rc; 919 } 920 921 /** Restart the system. 922 * 923 * @param sysinst System installer 924 * @return EOK on success or an error code 925 */ 926 static errno_t sysinst_restart(sysinst_t *sysinst) 927 { 928 errno_t rc; 929 system_t *system; 930 931 fibril_mutex_initialize(&shutdown_lock); 932 fibril_condvar_initialize(&shutdown_cv); 933 shutdown_stopped = false; 934 shutdown_failed = false; 935 936 rc = system_open(SYSTEM_DEFAULT, &sysinst_system_cb, NULL, &system); 937 if (rc != EOK) { 938 sysinst_error(sysinst, 939 "Failed opening system control service."); 940 return rc; 941 } 942 943 rc = system_restart(system); 944 if (rc != EOK) { 945 system_close(system); 946 sysinst_error(sysinst, "Failed requesting system restart."); 947 return rc; 948 } 949 950 fibril_mutex_lock(&shutdown_lock); 951 sysinst_debug(sysinst, "The system is shutting down..."); 952 953 while (!shutdown_stopped) 954 fibril_condvar_wait(&shutdown_cv, &shutdown_lock); 955 956 if (shutdown_failed) { 957 sysinst_error(sysinst, "Shutdown failed."); 958 system_close(system); 959 return rc; 960 } 961 962 log_msg(LOG_DEFAULT, LVL_NOTE, 963 "Shutdown complete. It is now safe to remove power."); 964 965 /* Sleep forever */ 966 while (true) 967 fibril_condvar_wait(&shutdown_cv, &shutdown_lock); 968 969 fibril_mutex_unlock(&shutdown_lock); 970 971 system_close(system); 972 return 0; 973 974 } 975 448 976 /** Install system to a device. 449 977 * 978 * @parma sysinst System installer 450 979 * @param dev Device to install to. 451 980 * @return EOK on success or an error code 452 981 */ 453 static errno_t sysinst_install(const char *dev) 454 { 455 errno_t rc; 456 service_id_t psvc_id; 457 458 rc = sysinst_label_dev(dev, &psvc_id); 459 if (rc != EOK) 460 return rc; 461 462 printf("FS created and mounted. Creating system directory structure.\n"); 463 rc = sysinst_setup_sysvol(); 464 if (rc != EOK) 465 return rc; 466 467 printf("Directories created. Copying boot files.\n"); 468 rc = sysinst_copy_boot_files(); 469 if (rc != EOK) 470 return rc; 471 472 printf("Boot files done. Configuring the system.\n"); 473 rc = sysinst_customize_initrd(); 474 if (rc != EOK) 475 return rc; 476 477 printf("Boot files done. Installing boot blocks.\n"); 478 rc = sysinst_copy_boot_blocks(dev); 479 if (rc != EOK) 480 return rc; 481 482 printf("Ejecting device.\n"); 483 rc = sysinst_eject_dev(psvc_id); 484 if (rc != EOK) 485 return rc; 486 487 return EOK; 982 static errno_t sysinst_install(sysinst_t *sysinst, const char *dev) 983 { 984 errno_t rc; 985 986 sysinst_action(sysinst, "Creating device label and file system."); 987 988 rc = sysinst_label_dev(sysinst, dev); 989 if (rc != EOK) 990 return rc; 991 992 sysinst_action(sysinst, "Creating system directory structure."); 993 rc = sysinst_setup_sysvol(sysinst); 994 if (rc != EOK) 995 return rc; 996 997 sysinst_action(sysinst, "Copying boot files."); 998 rc = sysinst_copy_boot_files(sysinst); 999 if (rc != EOK) 1000 return rc; 1001 1002 sysinst_action(sysinst, "Configuring the system."); 1003 rc = sysinst_customize_initrd(sysinst); 1004 if (rc != EOK) 1005 return rc; 1006 1007 sysinst_action(sysinst, "Finishing system volume."); 1008 rc = sysinst_finish_dev(sysinst); 1009 if (rc != EOK) 1010 return rc; 1011 1012 sysinst_action(sysinst, "Installing boot blocks."); 1013 rc = sysinst_copy_boot_blocks(sysinst, dev); 1014 if (rc != EOK) 1015 return rc; 1016 1017 sysinst_action(sysinst, "Ejecting installation media."); 1018 rc = sysinst_eject_phys_by_mp(sysinst, CD_MOUNT_POINT); 1019 if (rc != EOK) 1020 return rc; 1021 1022 return EOK; 1023 } 1024 1025 /** Installation fibril. 1026 * 1027 * @param arg Argument (sysinst_t *) 1028 * @return EOK on success or an error code 1029 */ 1030 static errno_t sysinst_install_fibril(void *arg) 1031 { 1032 sysinst_t *sysinst = (sysinst_t *)arg; 1033 unsigned i; 1034 errno_t rc; 1035 1036 (void)sysinst; 1037 1038 i = 0; 1039 while (default_devs[i] != NULL) { 1040 rc = sysinst_check_dev(default_devs[i]); 1041 if (rc == EOK) 1042 break; 1043 ++i; 1044 } 1045 1046 if (default_devs[i] == NULL) { 1047 sysinst_error(sysinst, "Cannot determine installation device."); 1048 rc = ENOENT; 1049 goto error; 1050 } 1051 1052 rc = sysinst_install(sysinst, default_devs[i]); 1053 if (rc != EOK) 1054 goto error; 1055 1056 sysinst_progress_destroy(sysinst->progress); 1057 rc = sysinst_restart_dlg_create(sysinst); 1058 if (rc != EOK) 1059 goto error; 1060 1061 return EOK; 1062 error: 1063 ui_lock(sysinst->ui); 1064 sysinst_progress_destroy(sysinst->progress); 1065 (void)sysinst_error_msg_create(sysinst); 1066 ui_unlock(sysinst->ui); 1067 return rc; 1068 } 1069 1070 /** Create installation progress window. 1071 * 1072 * @param sysinst System installer 1073 * @param rprogress Place to store pointer to new progress window 1074 * @return EOK on success or an error code 1075 */ 1076 static errno_t sysinst_progress_create(sysinst_t *sysinst, 1077 sysinst_progress_t **rprogress) 1078 { 1079 ui_wnd_params_t params; 1080 ui_window_t *window = NULL; 1081 gfx_rect_t rect; 1082 gfx_rect_t arect; 1083 ui_resource_t *ui_res; 1084 sysinst_progress_t *progress; 1085 ui_fixed_t *fixed = NULL; 1086 errno_t rc; 1087 1088 ui_wnd_params_init(¶ms); 1089 params.caption = "System Installation"; 1090 params.style &= ~ui_wds_titlebar; 1091 params.flags |= ui_wndf_topmost; 1092 params.placement = ui_wnd_place_center; 1093 if (ui_is_textmode(sysinst->ui)) { 1094 params.rect.p0.x = 0; 1095 params.rect.p0.y = 0; 1096 params.rect.p1.x = 64; 1097 params.rect.p1.y = 5; 1098 } else { 1099 params.rect.p0.x = 0; 1100 params.rect.p0.y = 0; 1101 params.rect.p1.x = 500; 1102 params.rect.p1.y = 60; 1103 } 1104 1105 progress = calloc(1, sizeof(sysinst_progress_t)); 1106 if (progress == NULL) { 1107 rc = ENOMEM; 1108 sysinst_error(sysinst, "Out of memory."); 1109 goto error; 1110 } 1111 1112 rc = ui_window_create(sysinst->ui, ¶ms, &window); 1113 if (rc != EOK) { 1114 sysinst_error(sysinst, "Error creating window."); 1115 goto error; 1116 } 1117 1118 ui_window_set_cb(window, &progress_window_cb, (void *)sysinst); 1119 1120 ui_res = ui_window_get_res(window); 1121 1122 rc = ui_fixed_create(&fixed); 1123 if (rc != EOK) { 1124 sysinst_error(sysinst, "Error creating fixed layout."); 1125 goto error; 1126 } 1127 1128 rc = ui_label_create(ui_res, "Installing system. Please wait...", 1129 &progress->label); 1130 if (rc != EOK) { 1131 sysinst_error(sysinst, "Error creating label."); 1132 goto error; 1133 } 1134 1135 ui_window_get_app_rect(window, &arect); 1136 1137 if (ui_is_textmode(sysinst->ui)) { 1138 rect.p0.x = arect.p0.x; 1139 rect.p0.y = arect.p0.y; 1140 rect.p1.x = arect.p1.x; 1141 rect.p1.y = 2; 1142 } else { 1143 rect.p0.x = arect.p0.x; 1144 rect.p0.y = arect.p0.y; 1145 rect.p1.x = arect.p1.x; 1146 rect.p1.y = 30; 1147 } 1148 ui_label_set_rect(progress->label, &rect); 1149 ui_label_set_halign(progress->label, gfx_halign_center); 1150 ui_label_set_valign(progress->label, gfx_valign_center); 1151 1152 rc = ui_fixed_add(fixed, ui_label_ctl(progress->label)); 1153 if (rc != EOK) { 1154 sysinst_error(sysinst, "Error adding control to layout."); 1155 ui_label_destroy(progress->label); 1156 progress->label = NULL; 1157 goto error; 1158 } 1159 1160 rc = ui_label_create(ui_res, "", 1161 &progress->action); 1162 if (rc != EOK) { 1163 sysinst_error(sysinst, "Error creating label."); 1164 goto error; 1165 } 1166 1167 if (ui_is_textmode(sysinst->ui)) { 1168 rect.p0.x = arect.p0.x; 1169 rect.p0.y = 3; 1170 rect.p1.x = arect.p1.x; 1171 rect.p1.y = arect.p1.y; 1172 } else { 1173 rect.p0.x = arect.p0.x; 1174 rect.p0.y = 30; 1175 rect.p1.x = arect.p1.x; 1176 rect.p1.y = arect.p1.y; 1177 } 1178 ui_label_set_rect(progress->action, &rect); 1179 ui_label_set_halign(progress->action, gfx_halign_center); 1180 ui_label_set_valign(progress->action, gfx_valign_center); 1181 1182 rc = ui_fixed_add(fixed, ui_label_ctl(progress->action)); 1183 if (rc != EOK) { 1184 sysinst_error(sysinst, "Error adding control to layout."); 1185 ui_label_destroy(progress->label); 1186 progress->label = NULL; 1187 goto error; 1188 } 1189 1190 ui_window_add(window, ui_fixed_ctl(fixed)); 1191 fixed = NULL; 1192 1193 rc = ui_window_paint(window); 1194 if (rc != EOK) { 1195 sysinst_error(sysinst, "Error painting window."); 1196 goto error; 1197 } 1198 1199 progress->window = window; 1200 progress->fixed = fixed; 1201 *rprogress = progress; 1202 return EOK; 1203 error: 1204 if (progress != NULL && progress->fixed != NULL) 1205 ui_fixed_destroy(progress->fixed); 1206 if (window != NULL) 1207 ui_window_destroy(window); 1208 if (progress != NULL) 1209 free(progress); 1210 return rc; 1211 } 1212 1213 /** Destroy installation progress window. 1214 * 1215 * @param sysinst System installer 1216 * @param rprogress Place to store pointer to new progress window 1217 * @return EOK on success or an error code 1218 */ 1219 static void sysinst_progress_destroy(sysinst_progress_t *progress) 1220 { 1221 if (progress == NULL) 1222 return; 1223 1224 ui_window_destroy(progress->window); 1225 free(progress); 1226 } 1227 1228 /** Set current action message. 1229 * 1230 * @param sysinst System installer 1231 * @param action Action text 1232 */ 1233 static void sysinst_action(sysinst_t *sysinst, const char *action) 1234 { 1235 if (sysinst->progress == NULL) 1236 return; 1237 1238 ui_label_set_text(sysinst->progress->action, action); 1239 ui_label_paint(sysinst->progress->action); 1240 log_msg(LOG_DEFAULT, LVL_NOTE, "%s", action); 1241 } 1242 1243 /** Set current error message. 1244 * 1245 * @param sysinst System installer 1246 * @param errmsg Error message 1247 */ 1248 static void sysinst_error(sysinst_t *sysinst, const char *errmsg) 1249 { 1250 str_cpy(sysinst->errmsg, sizeof(sysinst->errmsg), errmsg); 1251 log_msg(LOG_DEFAULT, LVL_ERROR, errmsg); 1252 } 1253 1254 /** Log a debug message. 1255 * 1256 * @param sysinst System installer 1257 * @param errmsg Error message 1258 */ 1259 static void sysinst_debug(sysinst_t *sysinst, const char *msg) 1260 { 1261 log_msg(LOG_DEFAULT, LVL_ERROR, msg); 1262 } 1263 1264 /** Start system installation. 1265 * 1266 * @param sysinst System installer 1267 * @return EOK on success or an error code 1268 */ 1269 static int sysinst_start(sysinst_t *sysinst) 1270 { 1271 errno_t rc; 1272 fid_t fid; 1273 1274 rc = sysinst_progress_create(sysinst, &sysinst->progress); 1275 if (rc != EOK) 1276 return rc; 1277 1278 fid = fibril_create(sysinst_install_fibril, (void *)sysinst); 1279 if (fid == 0) { 1280 sysinst_error(sysinst, "Out of memory."); 1281 return ENOMEM; 1282 } 1283 1284 fibril_add_ready(fid); 1285 return EOK; 1286 } 1287 1288 /** Create installation confirmation dialog. 1289 * 1290 * @param sysinst System installer 1291 * @return EOK on success or an error code 1292 */ 1293 static errno_t sysinst_confirm_create(sysinst_t *sysinst) 1294 { 1295 ui_msg_dialog_params_t params; 1296 ui_msg_dialog_t *dialog; 1297 errno_t rc; 1298 1299 ui_msg_dialog_params_init(¶ms); 1300 params.caption = "System installation"; 1301 params.text = "This will install HelenOS to your computer. Continue?"; 1302 params.choice = umdc_ok_cancel; 1303 params.flags |= umdf_topmost | umdf_center; 1304 1305 rc = ui_msg_dialog_create(sysinst->ui, ¶ms, &dialog); 1306 if (rc != EOK) 1307 return rc; 1308 1309 ui_msg_dialog_set_cb(dialog, &sysinst_confirm_cb, sysinst); 1310 return EOK; 1311 } 1312 1313 /** Create restart dialog. 1314 * 1315 * @param sysinst System installer 1316 * @return EOK on success or an error code 1317 */ 1318 static errno_t sysinst_restart_dlg_create(sysinst_t *sysinst) 1319 { 1320 ui_msg_dialog_params_t params; 1321 ui_msg_dialog_t *dialog; 1322 errno_t rc; 1323 1324 ui_msg_dialog_params_init(¶ms); 1325 params.caption = "Restart System"; 1326 params.text = "Installation complete. Restart the system?"; 1327 params.choice = umdc_ok_cancel; 1328 params.flags |= umdf_topmost | umdf_center; 1329 1330 rc = ui_msg_dialog_create(sysinst->ui, ¶ms, &dialog); 1331 if (rc != EOK) 1332 return rc; 1333 1334 ui_msg_dialog_set_cb(dialog, &sysinst_restart_dlg_cb, sysinst); 1335 return EOK; 1336 } 1337 1338 /** Run system installer on display. 1339 * 1340 * @param display_spec Display specification 1341 * @return EOK on success or an error code 1342 */ 1343 static errno_t sysinst_run(const char *display_spec) 1344 { 1345 ui_t *ui = NULL; 1346 sysinst_t *sysinst; 1347 ui_wnd_params_t params; 1348 errno_t rc; 1349 1350 sysinst = calloc(1, sizeof(sysinst_t)); 1351 if (sysinst == NULL) 1352 return ENOMEM; 1353 1354 rc = futil_create(&sysinst_futil_cb, (void *)sysinst, &sysinst->futil); 1355 if (rc != EOK) { 1356 printf("Out of memory.\n"); 1357 goto error; 1358 } 1359 1360 rc = ui_create(display_spec, &ui); 1361 if (rc != EOK) { 1362 printf("Error creating UI on display %s.\n", display_spec); 1363 goto error; 1364 } 1365 1366 sysinst->ui = ui; 1367 1368 ui_wnd_params_init(¶ms); 1369 params.caption = "System Installation"; 1370 params.style &= ~ui_wds_decorated; 1371 params.placement = ui_wnd_place_full_screen; 1372 params.flags |= ui_wndf_topmost | ui_wndf_nofocus; 1373 1374 rc = ui_window_create(sysinst->ui, ¶ms, &sysinst->bgwindow); 1375 if (rc != EOK) { 1376 printf("Error creating window.\n"); 1377 goto error; 1378 } 1379 1380 ui_window_set_cb(sysinst->bgwindow, &bg_window_cb, (void *)sysinst); 1381 1382 if (ui_is_textmode(sysinst->ui)) { 1383 rc = gfx_color_new_ega(0x17, &sysinst->bg_color); 1384 if (rc != EOK) { 1385 printf("Error allocating color.\n"); 1386 goto error; 1387 } 1388 } else { 1389 rc = gfx_color_new_rgb_i16(0x8000, 0xc800, 0xffff, &sysinst->bg_color); 1390 if (rc != EOK) { 1391 printf("Error allocating color.\n"); 1392 goto error; 1393 } 1394 } 1395 1396 rc = ui_window_paint(sysinst->bgwindow); 1397 if (rc != EOK) { 1398 printf("Error painting window.\n"); 1399 goto error; 1400 } 1401 1402 (void)sysinst_confirm_create(sysinst); 1403 1404 ui_run(ui); 1405 1406 if (sysinst->bgwindow != NULL) 1407 ui_window_destroy(sysinst->bgwindow); 1408 if (sysinst->system != NULL) 1409 system_close(sysinst->system); 1410 gfx_color_delete(sysinst->bg_color); 1411 ui_destroy(ui); 1412 free(sysinst); 1413 return EOK; 1414 error: 1415 if (sysinst->futil != NULL) 1416 futil_destroy(sysinst->futil); 1417 if (sysinst->system != NULL) 1418 system_close(sysinst->system); 1419 if (sysinst->bg_color != NULL) 1420 gfx_color_delete(sysinst->bg_color); 1421 if (sysinst->bgwindow != NULL) 1422 ui_window_destroy(sysinst->bgwindow); 1423 if (ui != NULL) 1424 ui_destroy(ui); 1425 free(sysinst); 1426 return rc; 1427 } 1428 1429 static void print_syntax(void) 1430 { 1431 printf("Syntax: " NAME " [-d <display-spec>]\n"); 488 1432 } 489 1433 490 1434 int main(int argc, char *argv[]) 491 1435 { 492 const char *dev = DEFAULT_DEV; 493 return sysinst_install(dev); 1436 const char *display_spec = UI_ANY_DEFAULT; 1437 errno_t rc; 1438 int i; 1439 1440 i = 1; 1441 while (i < argc && argv[i][0] == '-') { 1442 if (str_cmp(argv[i], "-d") == 0) { 1443 ++i; 1444 if (i >= argc) { 1445 printf("Argument missing.\n"); 1446 print_syntax(); 1447 return 1; 1448 } 1449 1450 display_spec = argv[i++]; 1451 } else { 1452 printf("Invalid option '%s'.\n", argv[i]); 1453 print_syntax(); 1454 return 1; 1455 } 1456 } 1457 1458 if (i < argc) { 1459 print_syntax(); 1460 return 1; 1461 } 1462 1463 if (log_init(NAME) != EOK) { 1464 printf(NAME ": Failed to initialize logging.\n"); 1465 return 1; 1466 } 1467 1468 rc = sysinst_run(display_spec); 1469 if (rc != EOK) 1470 return 1; 1471 1472 return 0; 494 1473 } 495 1474
Note:
See TracChangeset
for help on using the changeset viewer.