Ignore:
File:
1 edited

Legend:

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

    r61f28c4 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);
    160175static errno_t sysinst_eject_phys_by_mp(sysinst_t *, const char *);
    161 
    162 static futil_cb_t sysinst_futil_cb = {
    163         .copy_file = sysinst_futil_copy_file,
    164         .create_dir = sysinst_futil_create_dir
     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
    165182};
    166183
     
    247264 */
    248265static 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 dialog
     276 * @param arg Argument (sysinst_t *)
     277 * @param btn Button number
     278 * @param earg Entry argument
     279 */
     280static 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 dialog
     310 * @param arg Argument (sysinst_t *)
     311 */
     312static void sysinst_upgrade_confirm_close(ui_msg_dialog_t *dialog, void *arg)
    249313{
    250314        sysinst_t *sysinst = (sysinst_t *) arg;
     
    350414}
    351415
    352 /** 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.
    353471 *
    354472 * @param arg Argument (sysinst_t *)
     
    356474 * @param dest Destination path
    357475 */
    358 static void sysinst_futil_copy_file(void *arg, const char *src,
    359     const char *dest)
     476static void sysinst_fmgt_progress(void *arg, fmgt_progress_t *progress)
    360477{
    361478        sysinst_t *sysinst = (sysinst_t *)arg;
    362479        char buf[128];
    363480
    364         (void)src;
    365         snprintf(buf, sizeof(buf), "Copying %s.", dest);
    366         sysinst_action(sysinst, buf);
    367 }
    368 
    369 /** Called when futil is about to create a directory.
    370  *
    371  * @param arg Argument (sysinst_t *)
    372  * @param dest Destination path
    373  */
    374 static void sysinst_futil_create_dir(void *arg, const char *dest)
    375 {
    376         sysinst_t *sysinst = (sysinst_t *)arg;
    377         char buf[128];
    378 
    379         snprintf(buf, sizeof(buf), "Creating %s.", dest);
    380         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);
    381485}
    382486
     
    430534}
    431535
     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
    432637/** Label and mount the destination device.
    433638 *
    434639 * @param sysinst System installer
    435640 * @param dev Disk device to label
    436  * @param psvc_id Place to store service ID of the created partition
    437641 *
    438642 * @return EOK on success or an error code
     
    443647        fdisk_dev_t *fdev = NULL;
    444648        fdisk_part_t *part;
    445         fdisk_part_spec_t pspec;
    446         fdisk_part_info_t pinfo;
     649        fdisk_label_info_t linfo;
     650        bool create_label = false;
    447651        bool dir_created = false;
    448652        bool label_created = false;
    449         capa_spec_t capa;
    450653        service_id_t sid;
    451654        errno_t rc;
     
    483686        sysinst_debug(sysinst, "sysinst_label_dev(): create label");
    484687
    485         rc = fdisk_label_create(fdev, lt_mbr);
    486         if (rc != EOK) {
    487                 sysinst_error(sysinst, "Error creating label.");
    488                 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                }
    489715        }
    490716
     
    493719        sysinst_debug(sysinst, "sysinst_label_dev(): create partition");
    494720
    495         rc = fdisk_part_get_max_avail(fdev, spc_pri, &capa);
    496         if (rc != EOK) {
    497                 sysinst_error(sysinst,
    498                     "Error getting available capacity.");
    499                 goto error;
    500         }
    501 
    502         fdisk_pspec_init(&pspec);
    503         pspec.capacity = capa;
    504         pspec.pkind = lpk_primary;
    505         pspec.fstype = fs_ext4; /* Cannot be changed without modifying core.img */
    506         pspec.mountp = MOUNT_POINT;
    507         pspec.label = INST_VOL_LABEL;
    508 
    509         rc = fdisk_part_create(fdev, &pspec, &part);
    510         if (rc != EOK) {
    511                 sysinst_error(sysinst, "Error creating partition.");
    512                 goto error;
    513         }
    514 
    515         rc = fdisk_part_get_info(part, &pinfo);
    516         if (rc != EOK) {
    517                 sysinst_error(sysinst, "Error getting partition information.");
    518                 goto error;
    519         }
    520 
    521         sysinst_debug(sysinst, "sysinst_label_dev(): OK");
    522         fdisk_dev_close(fdev);
    523         fdisk_destroy(fdisk);
    524         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
    525770        return EOK;
    526771error:
     
    568813        char *path = NULL;
    569814        const char **cp;
     815        fmgt_flist_t *flist = NULL;
    570816        int rv;
    571817
     
    579825
    580826                rc = vfs_link_path(path, KIND_DIRECTORY, NULL);
    581                 if (rc != EOK) {
     827                if (rc != EOK && rc != EEXIST) {
    582828                        sysinst_error(sysinst, "Error creating directory.");
    583829                        goto error;
     
    593839
    594840        /* Copy initial configuration files */
    595         rc = futil_rcopy_contents(sysinst->futil, CFG_FILES_SRC,
    596             CFG_FILES_DEST);
     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);
    597856        if (rc != EOK) {
    598857                sysinst_error(sysinst, "Error copying initial configuration "
    599858                    "files.");
    600                 return rc;
    601         }
    602 
     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");
    603865        return EOK;
    604866error:
     867        if (flist != NULL)
     868                fmgt_flist_destroy(flist);
    605869        if (path != NULL)
    606870                free(path);
     
    614878static errno_t sysinst_copy_boot_files(sysinst_t *sysinst)
    615879{
     880        fmgt_flist_t *flist = NULL;
    616881        errno_t rc;
    617882
    618883        log_msg(LOG_DEFAULT, LVL_NOTE,
    619884            "sysinst_copy_boot_files(): copy bootloader files");
    620         rc = futil_rcopy_contents(sysinst->futil, BOOT_FILES_SRC, MOUNT_POINT);
     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);
    621896        if (rc != EOK) {
    622897                sysinst_error(sysinst, "Error copying bootloader "
    623898                    "files.");
    624                 return rc;
    625         }
    626 
     899                goto error;
     900        }
     901
     902        fmgt_flist_destroy(flist);
    627903        sysinst_debug(sysinst, "sysinst_copy_boot_files(): OK");
    628904        return EOK;
     905error:
     906        if (flist != NULL)
     907                fmgt_flist_destroy(flist);
     908        return rc;
    629909}
    630910
     
    7401020}
    7411021
     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
    7421071/** Copy boot blocks.
    7431072 *
     
    7651094            "sysinst_copy_boot_blocks: Read boot block image.");
    7661095
    767         rc = futil_get_file(sysinst->futil,
    768             BOOT_FILES_SRC "/boot/grub/i386-pc/boot.img",
     1096        rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/boot.img",
    7691097            &boot_img, &boot_img_size);
    770         if (rc != EOK || boot_img_size != 512)
     1098        if (rc != EOK || boot_img_size != 512) {
     1099                sysinst_error(sysinst, "Error reading boot block image.");
    7711100                return EIO;
     1101        }
    7721102
    7731103        log_msg(LOG_DEFAULT, LVL_NOTE,
    7741104            "sysinst_copy_boot_blocks: Read GRUB core image.");
    7751105
    776         rc = futil_get_file(sysinst->futil,
    777             BOOT_FILES_SRC "/boot/grub/i386-pc/core.img",
     1106        rc = sysinst_get_file(BOOT_FILES_SRC "/grub/i386-pc/core.img",
    7781107            &core_img, &core_img_size);
    779         if (rc != EOK)
     1108        if (rc != EOK) {
     1109                sysinst_error(sysinst, "Error reading GRUB core image.");
    7801110                return EIO;
     1111        }
    7811112
    7821113        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    7911122
    7921123        rc = block_init(sid);
    793         if (rc != EOK)
     1124        if (rc != EOK) {
     1125                sysinst_error(sysinst, "Error opening block device.");
    7941126                return rc;
     1127        }
    7951128
    7961129        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    7981131
    7991132        rc = block_get_bsize(sid, &bsize);
    800         if (rc != EOK)
     1133        if (rc != EOK) {
     1134                sysinst_error(sysinst, "Error getting block size.");
    8011135                return rc;
     1136        }
    8021137
    8031138        if (bsize != 512) {
     
    8101145
    8111146        rc = block_read_direct(sid, BOOT_BLOCK_IDX, 1, bbuf);
    812         if (rc != EOK)
     1147        if (rc != EOK) {
     1148                sysinst_error(sysinst, "Error reading boot block.");
    8131149                return EIO;
     1150        }
    8141151
    8151152        core_start = 16;
     
    8421179
    8431180        rc = block_write_direct(sid, BOOT_BLOCK_IDX, 1, bbuf);
    844         if (rc != EOK)
     1181        if (rc != EOK) {
     1182                sysinst_error(sysinst, "Error writing boot block.");
    8451183                return EIO;
     1184        }
    8461185
    8471186        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    8501189        /* XXX Must pad last block with zeros */
    8511190        rc = block_write_direct(sid, core_start, core_blocks, core_img);
    852         if (rc != EOK)
     1191        if (rc != EOK) {
     1192                sysinst_error(sysinst, "Error writing GRUB core blocks.");
    8531193                return EIO;
     1194        }
    8541195
    8551196        log_msg(LOG_DEFAULT, LVL_NOTE,
     
    10041345        if (rc != EOK)
    10051346                goto error;
     1347        if (sysinst->quit)
     1348                return EOK;
    10061349
    10071350        clean_dev = true;
     
    10741417        sysinst_progress_destroy(sysinst->progress);
    10751418        sysinst->progress = NULL;
     1419
     1420        /* User decided not to upgrade system? */
     1421        if (sysinst->quit) {
     1422                ui_quit(sysinst->ui);
     1423                return EOK;
     1424        }
    10761425
    10771426        rc = sysinst_restart_dlg_create(sysinst);
     
    11151464                params.rect.p0.y = 0;
    11161465                params.rect.p1.x = 64;
    1117                 params.rect.p1.y = 5;
     1466                params.rect.p1.y = 7;
    11181467        } else {
    11191468                params.rect.p0.x = 0;
    11201469                params.rect.p0.y = 0;
    11211470                params.rect.p1.x = 500;
    1122                 params.rect.p1.y = 60;
     1471                params.rect.p1.y = 90;
    11231472        }
    11241473
     
    11461495        }
    11471496
     1497        /* Installing/upgrading system line */
    11481498        rc = ui_label_create(ui_res, "Installing system. Please wait...",
    11491499            &progress->label);
     
    11781528        }
    11791529
     1530        /* Action line */
    11801531        rc = ui_label_create(ui_res, "",
    11811532            &progress->action);
     
    11891540                rect.p0.y = 3;
    11901541                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;
    11911573                rect.p1.y = arect.p1.y;
    11921574        } else {
    11931575                rect.p0.x = arect.p0.x;
    1194                 rect.p0.y = 30;
     1576                rect.p0.y = 70;
    11951577                rect.p1.x = arect.p1.x;
    11961578                rect.p1.y = arect.p1.y;
    11971579        }
    1198         ui_label_set_rect(progress->action, &rect);
    1199         ui_label_set_halign(progress->action, gfx_halign_center);
    1200         ui_label_set_valign(progress->action, gfx_valign_center);
    1201 
    1202         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));
    12031585        if (rc != EOK) {
    12041586                sysinst_error(sysinst, "Error adding control to layout.");
     
    12461628}
    12471629
     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
     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
    12481646/** Set current action message.
    12491647 *
     
    13321730}
    13331731
    1334 /** Create restart dialog.
    1335  *
    1336  * @param sysinst System installer
    1337  * @return EOK on success or an error code
    1338  */
    1339 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)
    13401738{
    13411739        ui_msg_dialog_params_t params;
     
    13441742
    13451743        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);
    13461770        params.caption = "Restart System";
    1347         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
    13481777        params.choice = umdc_ok_cancel;
    13491778        params.flags |= umdf_topmost | umdf_center;
     
    13731802                return ENOMEM;
    13741803
    1375         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);
    13761808        if (rc != EOK) {
    13771809                printf("Out of memory.\n");
    13781810                goto error;
    13791811        }
     1812
     1813        fmgt_set_cb(sysinst->fmgt, &sysinst_fmgt_cb, (void *)sysinst);
     1814        fmgt_set_init_update(sysinst->fmgt, true);
    13801815
    13811816        rc = ui_create(display_spec, &ui);
     
    14211856        }
    14221857
    1423         (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        }
    14241863
    14251864        ui_run(ui);
     
    14341873        return EOK;
    14351874error:
    1436         if (sysinst->futil != NULL)
    1437                 futil_destroy(sysinst->futil);
     1875        if (sysinst->fmgt != NULL)
     1876                fmgt_destroy(sysinst->fmgt);
    14381877        if (sysinst->system != NULL)
    14391878                system_close(sysinst->system);
Note: See TracChangeset for help on using the changeset viewer.