Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/app/sysinst/sysinst.c

    r629b480 r2c21595  
    11/*
    2  * Copyright (c) 2025 Jiri Svoboda
     2 * Copyright (c) 2026 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    4141#include <errno.h>
    4242#include <fdisk.h>
    43 #include <futil.h>
     43#include <fmgt.h>
    4444#include <gfx/render.h>
    4545#include <io/log.h>
     
    7575#define DEFAULT_DEV_2 "devices/\\hw\\sys\\00:01.0\\ide1\\c0d0"
    7676//#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 1
     79/* File system type cannot be changed without modifying core.img */
     80#define INST_FSTYPE fs_ext4
    7781/** Volume label for the new file system */
    7882#define INST_VOL_LABEL "HelenOS"
     
    8791#define CD_MOUNT_POINT "/vol/" CD_VOL_LABEL
    8892
    89 #define BOOT_FILES_SRC CD_MOUNT_POINT
     93#define BOOT_FILES_SRC CD_MOUNT_POINT "/boot"
    9094#define BOOT_BLOCK_IDX 0 /* MBR */
    9195
    9296#define CFG_FILES_SRC "/cfg"
    93 #define CFG_FILES_DEST MOUNT_POINT "/cfg"
     97#define CFG_FILES_DEST MOUNT_POINT
    9498
    9599static const char *default_devs[] = {
     
    139143};
    140144
     145static void sysinst_upgrade_confirm_button(ui_msg_dialog_t *, void *, unsigned);
     146static void sysinst_upgrade_confirm_close(ui_msg_dialog_t *, void *);
     147
     148static ui_msg_dialog_cb_t sysinst_upgrade_confirm_cb = {
     149        .button = sysinst_upgrade_confirm_button,
     150        .close = sysinst_upgrade_confirm_close
     151};
     152
    141153static errno_t sysinst_restart_dlg_create(sysinst_t *);
    142154static void sysinst_restart_dlg_button(ui_msg_dialog_t *, void *, unsigned);
     
    151163static errno_t sysinst_restart(sysinst_t *);
    152164static void sysinst_progress_destroy(sysinst_progress_t *);
     165static void sysinst_progress(sysinst_t *, const char *);
    153166static void sysinst_action(sysinst_t *, const char *);
    154167static void sysinst_error(sysinst_t *, const char *);
    155168static void sysinst_debug(sysinst_t *, const char *);
    156169
    157 static void sysinst_futil_copy_file(void *, const char *, const char *);
    158 static void sysinst_futil_create_dir(void *, const char *);
     170static fmgt_exists_action_t sysinst_fmgt_exists_query(void *, fmgt_exists_t *);
     171static void sysinst_fmgt_action(void *, fmgt_action_t, const char *,
     172    const char *);
     173static void sysinst_fmgt_progress(void *, fmgt_progress_t *);
    159174static 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
     175static errno_t sysinst_eject_phys_by_mp(sysinst_t *, const char *);
     176static errno_t sysinst_upgrade_confirm_create(sysinst_t *);
     177
     178static fmgt_cb_t sysinst_fmgt_cb = {
     179        .exists_query = sysinst_fmgt_exists_query,
     180        .action = sysinst_fmgt_action,
     181        .progress = sysinst_fmgt_progress
    164182};
    165183
     
    253271}
    254272
    255 /** Restart system dialog OK button press.
     273/** Upgrade confirm dialog OK button press.
    256274 *
    257275 * @param dialog Message dialog
     
    260278 * @param earg Entry argument
    261279 */
    262 static void sysinst_restart_dlg_button(ui_msg_dialog_t *dialog, void *arg,
     280static void sysinst_upgrade_confirm_button(ui_msg_dialog_t *dialog, void *arg,
    263281    unsigned btn)
    264282{
     
    266284
    267285        ui_msg_dialog_destroy(dialog);
    268 
    269         (void)sysinst;
    270286
    271287        switch (btn) {
    272288        case 0:
    273289                /* 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 dialog
     310 * @param arg Argument (sysinst_t *)
     311 */
     312static 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 dialog
     323 * @param arg Argument (sysinst_t *)
     324 * @param btn Button number
     325 * @param earg Entry argument
     326 */
     327static 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);
    274341                (void)sysinst_restart(sysinst);
    275342                break;
     
    347414}
    348415
    349 /** Called when futil is starting to copy a file.
     416/** Called when fmgt hits an existing file while copying.
     417 *
     418 * @param arg Argument (sysinst_t *)
     419 * @param exists Information about existing file
     420 * @return Existing file recovery action
     421 */
     422fmgt_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 specify
     433         * whether to overwrite existing files.
     434         */
     435        if (sysinst->overwrite)
     436                return fmgt_exr_overwrite;
     437        else
     438                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 performed
     445 * @param src Source or only path
     446 * @param dest Destination path or @c NULL
     447 */
     448static 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.
    350471 *
    351472 * @param arg Argument (sysinst_t *)
     
    353474 * @param dest Destination path
    354475 */
    355 static void sysinst_futil_copy_file(void *arg, const char *src,
    356     const char *dest)
     476static void sysinst_fmgt_progress(void *arg, fmgt_progress_t *progress)
    357477{
    358478        sysinst_t *sysinst = (sysinst_t *)arg;
    359479        char buf[128];
    360480
    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);
     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);
    378485}
    379486
     
    427534}
    428535
     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 */
     544static 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;
     582error:
     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 */
     593static errno_t sysinst_inst_part_create(sysinst_t *sysinst, fdisk_dev_t *fdev)
     594{
     595        fdisk_part_t *part;
     596        fdisk_part_spec_t pspec;
     597        fdisk_part_info_t pinfo;
     598        capa_spec_t capa;
     599        errno_t rc;
     600
     601        sysinst_debug(sysinst, "sysinst_inst_part_create(): get maximum available block");
     602
     603        rc = fdisk_part_get_max_avail(fdev, spc_pri, &capa);
     604        if (rc != EOK) {
     605                sysinst_error(sysinst,
     606                    "Error getting available capacity.");
     607                goto error;
     608        }
     609
     610        fdisk_pspec_init(&pspec);
     611        pspec.capacity = capa;
     612        pspec.pkind = lpk_primary;
     613        pspec.fstype = INST_FSTYPE; /* Cannot be changed without modifying core.img */
     614        pspec.mountp = MOUNT_POINT;
     615        pspec.index = INST_PART_IDX; /* Cannot be changed without modifying core.img */
     616        pspec.label = INST_VOL_LABEL;
     617
     618        rc = fdisk_part_create(fdev, &pspec, &part);
     619        if (rc != EOK) {
     620                sysinst_error(sysinst, "Error creating partition.");
     621                goto error;
     622        }
     623
     624        rc = fdisk_part_get_info(part, &pinfo);
     625        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;
     633error:
     634        return rc;
     635}
     636
    429637/** Label and mount the destination device.
    430638 *
    431639 * @param sysinst System installer
    432640 * @param dev Disk device to label
    433  * @param psvc_id Place to store service ID of the created partition
    434641 *
    435642 * @return EOK on success or an error code
     
    440647        fdisk_dev_t *fdev = NULL;
    441648        fdisk_part_t *part;
    442         fdisk_part_spec_t pspec;
    443         fdisk_part_info_t pinfo;
     649        fdisk_label_info_t linfo;
     650        bool create_label = false;
    444651        bool dir_created = false;
    445652        bool label_created = false;
    446         capa_spec_t capa;
    447653        service_id_t sid;
    448654        errno_t rc;
     
    480686        sysinst_debug(sysinst, "sysinst_label_dev(): create label");
    481687
    482         rc = fdisk_label_create(fdev, lt_mbr);
    483         if (rc != EOK) {
    484                 sysinst_error(sysinst, "Error creating label.");
    485                 goto error;
     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                }
    486715        }
    487716
     
    490719        sysinst_debug(sysinst, "sysinst_label_dev(): create partition");
    491720
    492         rc = fdisk_part_get_max_avail(fdev, spc_pri, &capa);
    493         if (rc != EOK) {
    494                 sysinst_error(sysinst,
    495                     "Error getting available capacity.");
    496                 goto error;
    497         }
    498 
    499         fdisk_pspec_init(&pspec);
    500         pspec.capacity = capa;
    501         pspec.pkind = lpk_primary;
    502         pspec.fstype = fs_ext4; /* Cannot be changed without modifying core.img */
    503         pspec.mountp = MOUNT_POINT;
    504         pspec.label = INST_VOL_LABEL;
    505 
    506         rc = fdisk_part_create(fdev, &pspec, &part);
    507         if (rc != EOK) {
    508                 sysinst_error(sysinst, "Error creating partition.");
    509                 goto error;
    510         }
    511 
    512         rc = fdisk_part_get_info(part, &pinfo);
    513         if (rc != EOK) {
    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;
     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
    522770        return EOK;
    523771error:
     
    565813        char *path = NULL;
    566814        const char **cp;
     815        fmgt_flist_t *flist = NULL;
    567816        int rv;
    568817
     
    576825
    577826                rc = vfs_link_path(path, KIND_DIRECTORY, NULL);
    578                 if (rc != EOK) {
     827                if (rc != EOK && rc != EEXIST) {
    579828                        sysinst_error(sysinst, "Error creating directory.");
    580829                        goto error;
     
    590839
    591840        /* 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;
    596 
     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");
    597865        return EOK;
    598866error:
     867        if (flist != NULL)
     868                fmgt_flist_destroy(flist);
    599869        if (path != NULL)
    600870                free(path);
     
    608878static errno_t sysinst_copy_boot_files(sysinst_t *sysinst)
    609879{
     880        fmgt_flist_t *flist = NULL;
    610881        errno_t rc;
    611882
    612883        log_msg(LOG_DEFAULT, LVL_NOTE,
    613884            "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 
     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);
    618903        sysinst_debug(sysinst, "sysinst_copy_boot_files(): OK");
    619904        return EOK;
     905error:
     906        if (flist != NULL)
     907                fmgt_flist_destroy(flist);
     908        return rc;
    620909}
    621910
     
    7311020}
    7321021
     1022/** Return file contents as a heap-allocated block of bytes.
     1023 *
     1024 * @param srcp File path
     1025 * @param rdata Place to store pointer to data
     1026 * @param rsize Place to store size of data
     1027 *
     1028 * @return EOK on success, ENOENT if failed to open file, EIO on other
     1029 *         I/O error, ENOMEM if out of memory
     1030 */
     1031static 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
    7331071/** Copy boot blocks.
    7341072 *
     
    7561094            "sysinst_copy_boot_blocks: Read boot block image.");
    7571095
    758         rc = futil_get_file(sysinst->futil,
    759             BOOT_FILES_SRC "/boot/grub/i386-pc/boot.img",
     1096        rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/boot.img",
    7601097            &boot_img, &boot_img_size);
    761         if (rc != EOK || boot_img_size != 512)
     1098        if (rc != EOK || boot_img_size != 512) {
     1099                sysinst_error(sysinst, "Error reading boot block image.");
    7621100                return EIO;
     1101        }
    7631102
    7641103        log_msg(LOG_DEFAULT, LVL_NOTE,
    7651104            "sysinst_copy_boot_blocks: Read GRUB core image.");
    7661105
    767         rc = futil_get_file(sysinst->futil,
    768             BOOT_FILES_SRC "/boot/grub/i386-pc/core.img",
     1106        rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/core.img",
    7691107            &core_img, &core_img_size);
    770         if (rc != EOK)
     1108        if (rc != EOK) {
     1109                sysinst_error(sysinst, "Error reading GRUB core image.");
    7711110                return EIO;
     1111        }
    7721112
    7731113        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    7821122
    7831123        rc = block_init(sid);
    784         if (rc != EOK)
     1124        if (rc != EOK) {
     1125                sysinst_error(sysinst, "Error opening block device.");
    7851126                return rc;
     1127        }
    7861128
    7871129        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    7891131
    7901132        rc = block_get_bsize(sid, &bsize);
    791         if (rc != EOK)
     1133        if (rc != EOK) {
     1134                sysinst_error(sysinst, "Error getting block size.");
    7921135                return rc;
     1136        }
    7931137
    7941138        if (bsize != 512) {
     
    8011145
    8021146        rc = block_read_direct(sid, BOOT_BLOCK_IDX, 1, bbuf);
    803         if (rc != EOK)
     1147        if (rc != EOK) {
     1148                sysinst_error(sysinst, "Error reading boot block.");
    8041149                return EIO;
     1150        }
    8051151
    8061152        core_start = 16;
     
    8331179
    8341180        rc = block_write_direct(sid, BOOT_BLOCK_IDX, 1, bbuf);
    835         if (rc != EOK)
     1181        if (rc != EOK) {
     1182                sysinst_error(sysinst, "Error writing boot block.");
    8361183                return EIO;
     1184        }
    8371185
    8381186        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    8411189        /* XXX Must pad last block with zeros */
    8421190        rc = block_write_direct(sid, core_start, core_blocks, core_img);
    843         if (rc != EOK)
     1191        if (rc != EOK) {
     1192                sysinst_error(sysinst, "Error writing GRUB core blocks.");
    8441193                return EIO;
     1194        }
    8451195
    8461196        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    8911241        errno_t rc;
    8921242
     1243        log_msg(LOG_DEFAULT, LVL_NOTE,
     1244            "sysinst_eject_phys_by_mp(%s)", path);
     1245
    8931246        rc = vol_create(&vol);
    8941247        if (rc != EOK) {
     
    9341287        shutdown_failed = false;
    9351288
     1289        sysinst_action(sysinst, "Restarting the system.");
     1290
    9361291        rc = system_open(SYSTEM_DEFAULT, &sysinst_system_cb, NULL, &system);
    9371292        if (rc != EOK) {
     
    9831338{
    9841339        errno_t rc;
     1340        bool clean_dev = false;
    9851341
    9861342        sysinst_action(sysinst, "Creating device label and file system.");
     
    9881344        rc = sysinst_label_dev(sysinst, dev);
    9891345        if (rc != EOK)
    990                 return rc;
     1346                goto error;
     1347        if (sysinst->quit)
     1348                return EOK;
     1349
     1350        clean_dev = true;
    9911351
    9921352        sysinst_action(sysinst, "Creating system directory structure.");
    9931353        rc = sysinst_setup_sysvol(sysinst);
    9941354        if (rc != EOK)
    995                 return rc;
     1355                goto error;
    9961356
    9971357        sysinst_action(sysinst, "Copying boot files.");
    9981358        rc = sysinst_copy_boot_files(sysinst);
    9991359        if (rc != EOK)
    1000                 return rc;
     1360                goto error;
    10011361
    10021362        sysinst_action(sysinst, "Configuring the system.");
    10031363        rc = sysinst_customize_initrd(sysinst);
    10041364        if (rc != EOK)
    1005                 return rc;
     1365                goto error;
    10061366
    10071367        sysinst_action(sysinst, "Finishing system volume.");
    10081368        rc = sysinst_finish_dev(sysinst);
    10091369        if (rc != EOK)
    1010                 return rc;
     1370                goto error;
     1371
     1372        clean_dev = false;
    10111373
    10121374        sysinst_action(sysinst, "Installing boot blocks.");
     
    10151377                return rc;
    10161378
    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 
    10221379        return EOK;
     1380error:
     1381        if (clean_dev)
     1382                (void)sysinst_finish_dev(sysinst);
     1383        return rc;
    10231384}
    10241385
     
    10551416
    10561417        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
    10571426        rc = sysinst_restart_dlg_create(sysinst);
    10581427        if (rc != EOK)
     
    10951464                params.rect.p0.y = 0;
    10961465                params.rect.p1.x = 64;
    1097                 params.rect.p1.y = 5;
     1466                params.rect.p1.y = 7;
    10981467        } else {
    10991468                params.rect.p0.x = 0;
    11001469                params.rect.p0.y = 0;
    11011470                params.rect.p1.x = 500;
    1102                 params.rect.p1.y = 60;
     1471                params.rect.p1.y = 90;
    11031472        }
    11041473
     
    11261495        }
    11271496
     1497        /* Installing/upgrading system line */
    11281498        rc = ui_label_create(ui_res, "Installing system. Please wait...",
    11291499            &progress->label);
     
    11581528        }
    11591529
     1530        /* Action line */
    11601531        rc = ui_label_create(ui_res, "",
    11611532            &progress->action);
     
    11691540                rect.p0.y = 3;
    11701541                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;
    11711573                rect.p1.y = arect.p1.y;
    11721574        } else {
    11731575                rect.p0.x = arect.p0.x;
    1174                 rect.p0.y = 30;
     1576                rect.p0.y = 70;
    11751577                rect.p1.x = arect.p1.x;
    11761578                rect.p1.y = arect.p1.y;
    11771579        }
    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));
     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));
    11831585        if (rc != EOK) {
    11841586                sysinst_error(sysinst, "Error adding control to layout.");
     
    12261628}
    12271629
    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 {
     1630/** Set current progress message.
     1631 *
     1632 * @param sysinst System installer
     1633 * @param progress Progress text
     1634 */
     1635static void sysinst_progress(sysinst_t *sysinst, const char *progress)
     1636{
     1637        log_msg(LOG_DEFAULT, LVL_NOTE, "%s", progress);
     1638
    12351639        if (sysinst->progress == NULL)
    12361640                return;
    12371641
     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 */
     1651static 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
    12381658        ui_label_set_text(sysinst->progress->action, action);
    12391659        ui_label_paint(sysinst->progress->action);
    1240         log_msg(LOG_DEFAULT, LVL_NOTE, "%s", action);
    12411660}
    12421661
     
    13111730}
    13121731
    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)
     1732/** Create upgrade confirmation dialog.
     1733 *
     1734 * @param sysinst System installer
     1735 * @return EOK on success or an error code
     1736 */
     1737static errno_t sysinst_upgrade_confirm_create(sysinst_t *sysinst)
    13191738{
    13201739        ui_msg_dialog_params_t params;
     
    13231742
    13241743        ui_msg_dialog_params_init(&params);
     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, &params, &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 */
     1763static 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(&params);
    13251770        params.caption = "Restart System";
    1326         params.text = "Installation complete. Restart the 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
    13271777        params.choice = umdc_ok_cancel;
    13281778        params.flags |= umdf_topmost | umdf_center;
     
    13521802                return ENOMEM;
    13531803
    1354         rc = futil_create(&sysinst_futil_cb, (void *)sysinst, &sysinst->futil);
     1804        fibril_condvar_initialize(&sysinst->responded_cv);
     1805        fibril_mutex_initialize(&sysinst->responded_lock);
     1806
     1807        rc = fmgt_create(&sysinst->fmgt);
    13551808        if (rc != EOK) {
    13561809                printf("Out of memory.\n");
    13571810                goto error;
    13581811        }
     1812
     1813        fmgt_set_cb(sysinst->fmgt, &sysinst_fmgt_cb, (void *)sysinst);
     1814        fmgt_set_init_update(sysinst->fmgt, true);
    13591815
    13601816        rc = ui_create(display_spec, &ui);
     
    14001856        }
    14011857
    1402         (void)sysinst_confirm_create(sysinst);
     1858        rc = sysinst_confirm_create(sysinst);
     1859        if (rc != EOK) {
     1860                printf("Error creating window.\n");
     1861                goto error;
     1862        }
    14031863
    14041864        ui_run(ui);
     
    14131873        return EOK;
    14141874error:
    1415         if (sysinst->futil != NULL)
    1416                 futil_destroy(sysinst->futil);
     1875        if (sysinst->fmgt != NULL)
     1876                fmgt_destroy(sysinst->fmgt);
    14171877        if (sysinst->system != NULL)
    14181878                system_close(sysinst->system);
Note: See TracChangeset for help on using the changeset viewer.