From df8eababb31187582db57d47cd83f7ecfb4f1ee9 Mon Sep 17 00:00:00 2001 From: Jiri Svoboda Date: Sat, 6 Oct 2018 23:14:14 +0200 Subject: [PATCH] Let installer amend RAM disk image with volume server configuration. --- boot/Makefile | 8 +- tools/mkext2.py | 2 +- uspace/app/sysinst/Makefile | 6 +- uspace/app/sysinst/rdimg.c | 219 ++++++++++++++++++++++++++++++ uspace/app/sysinst/rdimg.h | 55 ++++++++ uspace/app/sysinst/sysinst.c | 93 +++++++++++++ uspace/app/sysinst/types/volume.h | 1 + uspace/app/sysinst/volume.c | 1 + uspace/app/sysinst/volume.h | 1 + uspace/srv/volsrv/volsrv.c | 2 +- uspace/srv/volsrv/volume.c | 1 + 11 files changed, 383 insertions(+), 6 deletions(-) create mode 100644 uspace/app/sysinst/rdimg.c create mode 100644 uspace/app/sysinst/rdimg.h create mode 120000 uspace/app/sysinst/types/volume.h create mode 120000 uspace/app/sysinst/volume.c create mode 120000 uspace/app/sysinst/volume.h diff --git a/boot/Makefile b/boot/Makefile index 3c97a6c8e6..214e37bc10 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -38,8 +38,8 @@ endif build_dist: clean_dist mkdir -p "$(DIST_PATH)/app/" - mkdir -p "$(DIST_PATH)/cfg/net/" - mkdir -p "$(DIST_PATH)/data/cfg/" + mkdir -p "$(DIST_PATH)/cfg/" + mkdir -p "$(DIST_PATH)/data/" mkdir -p "$(DIST_PATH)/lib/" mkdir -p "$(DIST_PATH)/loc/" mkdir -p "$(DIST_PATH)/log/" @@ -47,6 +47,7 @@ build_dist: clean_dist mkdir -p "$(DIST_PATH)/test/" mkdir -p "$(DIST_PATH)/tmp/" mkdir -p "$(DIST_PATH)/vol/" + mkdir -p "$(DIST_PATH)/w/" for file in $(RD_SRVS) ; do \ cp "$$file" "$(DIST_PATH)/srv/" ; \ done @@ -134,6 +135,8 @@ endif clean_dist: rm -f $(INITRD).img $(COMPS).s $(COMPS).h $(COMPS)_desc.c $(COMPONENTS_DEFLATE) $(COMPS).o $(COMPS)_desc.o $(COMPS).zip $(LINK) find $(USPACE_PATH)/dist -mindepth 1 -maxdepth 1 -type f -exec rm \{\} \; + rm -f $(USPACE_PATH)/dist/app/* + rm -f $(USPACE_PATH)/dist/cfg/* rm -f $(USPACE_PATH)/dist/srv/* rm -rf $(USPACE_PATH)/dist/drv/* rm -rf $(USPACE_PATH)/dist/lib/* @@ -141,3 +144,4 @@ clean_dist: rm -f $(USPACE_PATH)/dist/app/* rm -f $(USPACE_PATH)/dist/test/* rm -f $(USPACE_PATH)/dist/cfg/net/* + rm -f $(USPACE_PATH)/dist/w/* diff --git a/tools/mkext2.py b/tools/mkext2.py index a87c68d06c..6765f3a411 100755 --- a/tools/mkext2.py +++ b/tools/mkext2.py @@ -309,7 +309,7 @@ def write_superblock(self, block_group): sb.features_incompatible = 2 # filetype sb.features_read_only = 0 sb.uuid = self.uuid.bytes_le - sb.volume_name = 'HelenOS rdimage\0' + sb.volume_name = 'HelenOS-rd\0\0\0\0\0\0' self.outf.write(bytes(sb.pack())) def write_all_metadata(self): diff --git a/uspace/app/sysinst/Makefile b/uspace/app/sysinst/Makefile index 8bee52a866..77837b1972 100644 --- a/uspace/app/sysinst/Makefile +++ b/uspace/app/sysinst/Makefile @@ -27,12 +27,14 @@ # USPACE_PREFIX = ../.. -LIBS = block fdisk +LIBS = block fdisk sif BINARY = sysinst SOURCES = \ futil.c \ - sysinst.c + rdimg.c \ + sysinst.c \ + volume.c include $(USPACE_PREFIX)/Makefile.common diff --git a/uspace/app/sysinst/rdimg.c b/uspace/app/sysinst/rdimg.c new file mode 100644 index 0000000000..0d5a1aa206 --- /dev/null +++ b/uspace/app/sysinst/rdimg.c @@ -0,0 +1,219 @@ +/* + * Copyright (c) 2018 Jiri Svoboda + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** @addtogroup sysinst + * @{ + */ +/** @file RAM disk image manipulation + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "rdimg.h" + +#define FILE_BD "/srv/file_bd" +#define RD_SVC "bd/iird" +#define RD_LABEL "HelenOS-rd" + +/** Find volume by volume label. */ +static errno_t rd_img_part_by_label(vol_t *vol, const char *label, + service_id_t *rid) +{ + vol_part_info_t vinfo; + service_id_t *part_ids = NULL; + size_t nparts; + size_t i; + errno_t rc; + + rc = vol_get_parts(vol, &part_ids, &nparts); + if (rc != EOK) { + printf("Error getting list of volumes.\n"); + goto out; + } + + for (i = 0; i < nparts; i++) { + rc = vol_part_info(vol, part_ids[i], &vinfo); + if (rc != EOK) { + printf("Error getting volume information.\n"); + rc = EIO; + goto out; + } + + if (str_cmp(vinfo.label, label) == 0) { + *rid = part_ids[i]; + rc = EOK; + goto out; + } + } + + rc = ENOENT; +out: + free(part_ids); + return rc; +} + +/** Open RAM disk image. + * + * @param imgpath Image path + * @param rpath Place to store pointer to newly allocated string, the path to + * the mounted RAM disk. + * @param rimg Place to store pointer to newly allocated object. + * + * @return EOK on success or an error code + */ +errno_t rd_img_open(const char *imgpath, char **rpath, rd_img_t **rimg) +{ + rd_img_t *img = NULL; + char *rdpath = NULL; + errno_t rc; + task_id_t id; + task_wait_t wait; + task_exit_t texit; + vfs_stat_t stat; + int retval; + int cnt; + + printf("rd_img_open: begin\n"); + rdpath = str_dup("/vol/" RD_LABEL); + if (rdpath == NULL) { + rc = ENOMEM; + goto error; + } + + img = calloc(1, sizeof(rd_img_t)); + if (img == NULL) { + rc = ENOMEM; + goto error; + } + + printf("rd_img_open: spawn file_bd\n"); + rc = task_spawnl(&id, &wait, FILE_BD, FILE_BD, imgpath, RD_SVC, NULL); + if (rc != EOK) { + rc = EIO; + goto error; + } + + printf("rd_img_open: wait for file_bd\n"); + rc = task_wait(&wait, &texit, &retval); + if (rc != EOK || texit != TASK_EXIT_NORMAL) { + rc = EIO; + goto error; + } + + /* Wait for the RAM disk to become available */ + printf("rd_img_open: wait for RAM disk to be mounted\n"); + cnt = 10; + while (cnt > 0) { + rc = vfs_stat_path(rdpath, &stat); + if (rc == EOK) + break; + + fibril_sleep(1); + --cnt; + } + + if (cnt == 0) { + printf("rd_img_open: ran out of time\n"); + rc = EIO; + goto error; + } + + img->filebd_tid = id; + *rimg = img; + *rpath = rdpath; + printf("rd_img_open: success\n"); + return EOK; +error: + if (rdpath != NULL) + free(rdpath); + if (img != NULL) + free(img); + return rc; +} + +/** Close RAM disk image. + * + */ +errno_t rd_img_close(rd_img_t *img) +{ + errno_t rc; + service_id_t rd_svcid; + vol_t *vol = NULL; + + printf("rd_img_close: begin\n"); + + rc = vol_create(&vol); + if (rc != EOK) { + printf("Error opening volume management service.\n"); + rc = EIO; + goto error; + } + + printf("rd_img_close: Find RAM disk volume.\n"); + rc = rd_img_part_by_label(vol, RD_LABEL, &rd_svcid); + if (rc != EOK) { + printf("Error getting RAM disk service ID.\n"); + rc = EIO; + goto error; + } + + printf("rd_img_close: eject RAM disk volume\n"); + rc = vol_part_eject(vol, rd_svcid); + if (rc != EOK) { + printf("Error ejecting RAM disk volume.\n"); + rc = EIO; + goto error; + } + + vol_destroy(vol); + + rc = task_kill(img->filebd_tid); + if (rc != EOK) { + printf("Error killing file_bd.\n"); + rc = EIO; + goto error; + } + + free(img); + printf("rd_img_close: success\n"); + return EOK; +error: + free(img); + if (vol != NULL) + vol_destroy(vol); + return rc; +} + +/** @} + */ diff --git a/uspace/app/sysinst/rdimg.h b/uspace/app/sysinst/rdimg.h new file mode 100644 index 0000000000..a41887a863 --- /dev/null +++ b/uspace/app/sysinst/rdimg.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2018 Jiri Svoboda + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * - The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** @addtogroup sysinst + * @{ + */ +/** + * @file + * @brief + */ + +#ifndef RDIMG_H +#define RDIMG_H + +#include +#include + +/** Open RAM disk image */ +typedef struct { + /** Task ID of file_bd providing the RAM disk */ + task_id_t filebd_tid; +} rd_img_t; + +extern errno_t rd_img_open(const char *, char **, rd_img_t **); +extern errno_t rd_img_close(rd_img_t *); + +#endif + +/** @} + */ diff --git a/uspace/app/sysinst/sysinst.c b/uspace/app/sysinst/sysinst.c index d3efd179f6..d5ab6a5571 100644 --- a/uspace/app/sysinst/sysinst.c +++ b/uspace/app/sysinst/sysinst.c @@ -50,6 +50,8 @@ #include "futil.h" #include "grub.h" +#include "rdimg.h" +#include "volume.h" /** Device to install to * @@ -63,6 +65,8 @@ //#define DEFAULT_DEV "devices/\\hw\\pci0\\00:01.2\\uhci_rh\\usb01_a1\\mass-storage0\\l0" /** Volume label for the new file system */ #define INST_VOL_LABEL "HelenOS" +/** Mount point of system partition when running installed system */ +#define INST_VOL_MP "/w" #define MOUNT_POINT "/inst" @@ -174,6 +178,90 @@ static errno_t sysinst_copy_boot_files(void) return EOK; } +/** Set up configuration in the initial RAM disk. + * + * @return EOK on success or an error code + */ +static errno_t sysinst_customize_initrd(void) +{ + errno_t rc; + rd_img_t *rd = NULL; + char *rdpath = NULL; + char *path = NULL; + vol_volumes_t *volumes = NULL; + vol_volume_t *volume = NULL; + int rv; + + rc = rd_img_open(MOUNT_POINT "/boot/initrd.img", &rdpath, &rd); + if (rc != EOK) { + printf("Error opening initial RAM disk image.\n"); + goto error; + } + + rv = asprintf(&path, "%s%s", rdpath, "/cfg/volsrv.sif"); + if (rv < 0) { + rc = ENOMEM; + goto error; + } + + printf("Configuring volume server.\n"); + rc = vol_volumes_create(path, &volumes); + if (rc != EOK) { + printf("Error creating volume server configuration.\n"); + rc = EIO; + goto error; + } + + printf("Configuring volume server: look up volume\n"); + rc = vol_volume_lookup_ref(volumes, INST_VOL_LABEL, &volume); + if (rc != EOK) { + printf("Error creating volume server configuration.\n"); + rc = EIO; + goto error; + } + + printf("Configuring volume server: set mount point\n"); + rc = vol_volume_set_mountp(volume, INST_VOL_MP); + if (rc != EOK) { + printf("Error creating system partition configuration.\n"); + rc = EIO; + goto error; + } + + printf("Configuring volume server: delete reference\n"); + vol_volume_del_ref(volume); + volume = NULL; + printf("Configuring volume server: destroy volumes object\n"); + vol_volumes_destroy(volumes); + volumes = NULL; + + rc = rd_img_close(rd); + if (rc != EOK) { + printf("Error closing initial RAM disk image.\n"); + rc = EIO; + goto error; + } + + free(rdpath); + rdpath = NULL; + free(path); + path = NULL; + + return EOK; +error: + if (volume != NULL) + vol_volume_del_ref(volume); + if (volumes != NULL) + vol_volumes_destroy(volumes); + if (rd != NULL) + (void) rd_img_close(rd); + if (path != NULL) + free(path); + if (rdpath != NULL) + free(rdpath); + return rc; +} + /** Write unaligned 64-bit little-endian number. * * @param a Destination buffer @@ -331,6 +419,11 @@ static errno_t sysinst_install(const char *dev) if (rc != EOK) return rc; + printf("Boot files done. Configuring the system.\n"); + rc = sysinst_customize_initrd(); + if (rc != EOK) + return rc; + printf("Boot files done. Installing boot blocks.\n"); rc = sysinst_copy_boot_blocks(dev); if (rc != EOK) diff --git a/uspace/app/sysinst/types/volume.h b/uspace/app/sysinst/types/volume.h new file mode 120000 index 0000000000..fb0527c766 --- /dev/null +++ b/uspace/app/sysinst/types/volume.h @@ -0,0 +1 @@ +../../../srv/volsrv/types/volume.h \ No newline at end of file diff --git a/uspace/app/sysinst/volume.c b/uspace/app/sysinst/volume.c new file mode 120000 index 0000000000..0b1b99fe14 --- /dev/null +++ b/uspace/app/sysinst/volume.c @@ -0,0 +1 @@ +../../srv/volsrv/volume.c \ No newline at end of file diff --git a/uspace/app/sysinst/volume.h b/uspace/app/sysinst/volume.h new file mode 120000 index 0000000000..80e4a5b252 --- /dev/null +++ b/uspace/app/sysinst/volume.h @@ -0,0 +1 @@ +../../srv/volsrv/volume.h \ No newline at end of file diff --git a/uspace/srv/volsrv/volsrv.c b/uspace/srv/volsrv/volsrv.c index 25a9d7b7ed..2f0d400989 100644 --- a/uspace/srv/volsrv/volsrv.c +++ b/uspace/srv/volsrv/volsrv.c @@ -52,7 +52,7 @@ #define NAME "volsrv" -const char *vol_cfg_file = "/data/cfg/volsrv.sif"; +const char *vol_cfg_file = "/cfg/volsrv.sif"; static void vol_client_conn(ipc_call_t *, void *); diff --git a/uspace/srv/volsrv/volume.c b/uspace/srv/volsrv/volume.c index f6d079586d..3bfbf2d416 100644 --- a/uspace/srv/volsrv/volume.c +++ b/uspace/srv/volsrv/volume.c @@ -204,6 +204,7 @@ void vol_volumes_destroy(vol_volumes_t *volumes) link = list_first(&volumes->volumes); } + (void) sif_close(volumes->repo); free(volumes); }