Message ID | 1515775206-9174-1-git-send-email-sbabic@denx.de |
---|---|
State | Changes Requested |
Headers | show |
Series | [1/2] Allow again bootloader scripts | expand |
Hi Stefano, Am 12.01.2018 um 17:40 schrieb Stefano Babic: > commit ff12cd69445c0f49d44ad0b75dea6f6ec1b0e449 forbids to use a bootloader > script in the "images" section of sw-description. This avoids to set bootloader's > variables in the middle of an installation that can brick the device. > However, having a script is often much more comfortable as a list of couple > <name, value> inside sw-description. This allows again to have bootloader scripts, > but they must be inserted in the "bootenv" section of sw-description. What is the different between a script and a bootloader script? > Signed-off-by: Stefano Babic <sbabic@denx.de> > --- > core/parser.c | 2 + > corelib/installer.c | 108 +++++++++++++++++++++++++++++---------------- > corelib/stream_interface.c | 24 ++++++++-- > include/installer.h | 1 - > include/swupdate.h | 1 + > parser/parser.c | 44 +++++++++++++----- > 6 files changed, 126 insertions(+), 54 deletions(-) > > diff --git a/core/parser.c b/core/parser.c > index a1232bd..cdfbea8 100644 > --- a/core/parser.c > +++ b/core/parser.c > @@ -147,6 +147,8 @@ int parse(struct swupdate_cfg *sw, const char *descfile) > "images / files"); > ret |= check_handler_list(&sw->partitions, PARTITION_HANDLER, > "partitions"); > + ret |= check_handler_list(&sw->bootscripts, BOOTLOADER_HANDLER, > + "bootloader"); > if (ret) > return -EINVAL; > > diff --git a/corelib/installer.c b/corelib/installer.c > index fc3011e..9a67399 100644 > --- a/corelib/installer.c > +++ b/corelib/installer.c > @@ -233,6 +233,27 @@ static int prepare_boot_script(struct swupdate_cfg *cfg, const char *script) > return ret; > } > > +static int run_prepost_scripts(struct imglist *list, script_fn type) > +{ > + int ret; > + struct img_type *img; > + struct installer_handler *hnd; > + > + /* Scripts must be run before installing images */ > + LIST_FOREACH(img, list, next) { > + if (!img->is_script) > + continue; > + hnd = find_handler(img); > + if (hnd) { > + ret = hnd->installer(img, &type); > + if (ret) > + return ret; > + } > + } > + > + return 0; > +} > + > static int update_bootloader_env(void) > { > int ret = 0; > @@ -291,13 +312,14 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile) > /* Extract all scripts, preinstall scripts must be run now */ > const char* tmpdir_scripts = get_tmpdirscripts(); > ret = extract_scripts(fdsw, &sw->scripts, fromfile); > + ret |= extract_scripts(fdsw, &sw->bootscripts, fromfile); > if (ret) { > ERROR("extracting script to %s failed", tmpdir_scripts); > return ret; > } > > /* Scripts must be run before installing images */ > - ret = run_prepost_scripts(sw, PREINSTALL); > + ret = run_prepost_scripts(&sw->scripts, PREINSTALL); > if (ret) { > ERROR("execute preinstall scripts failed"); > return ret; > @@ -388,7 +410,7 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile) > > } > > - ret = run_prepost_scripts(sw, POSTINSTALL); > + ret = run_prepost_scripts(&sw->scripts, POSTINSTALL); > if (ret) { > ERROR("execute postinstall scripts failed"); > return ret; > @@ -397,31 +419,11 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile) > if (!LIST_EMPTY(&sw->bootloader)) > ret = update_bootloader_env(); > > - return ret; > -} > - > -int run_prepost_scripts(struct swupdate_cfg *sw, script_fn type) > -{ > - int ret; > - struct img_type *img; > - struct installer_handler *hnd; > - > - /* Scripts must be run before installing images */ > - LIST_FOREACH(img, &sw->scripts, next) { > - if (!img->is_script) > - continue; > - hnd = find_handler(img); > - if (hnd) { > - ret = hnd->installer(img, &type); > - if (ret) > - return ret; > - } > - } > + ret |= run_prepost_scripts(&sw->bootscripts, POSTINSTALL); > > - return 0; > + return ret; > } > > - > static void remove_sw_file(char __attribute__ ((__unused__)) *fname) > { > #ifndef CONFIG_NOCLEANUP > @@ -430,11 +432,42 @@ static void remove_sw_file(char __attribute__ ((__unused__)) *fname) > #endif > } > > +static void cleaup_img_entry(struct img_type *img) > +{ > + char *fn; > + int i; > + const char *tmp; > + > + if (img->fname[0]) { > + > + for (i = 0; i < 2; i++) { > + switch(i) { > + case 0: > + tmp = get_tmpdirscripts(); > + break; > + case 1: > + tmp = get_tmpdir(); > + break; > + } Maybe you could replace the switch by an array and use the ARRAY_SIZE instead of the fix number: const char *tmp[] = {get_tmpdirscripts(), get_tmpdir()} > + > + if (asprintf(&fn, "%s%s", tmp, img->fname) == ENOMEM_ASPRINTF) { > + ERROR("Path too long: %s%s", tmp, img->fname); > + } else { > + remove_sw_file(fn); > + free(fn); > + } > + } > + } > + dict_drop_db(&img->properties); > +} > + > void cleanup_files(struct swupdate_cfg *software) { > char fn[64]; > struct img_type *img; > struct hw_type *hw; > const char* TMPDIR = get_tmpdir(); > + int count; > + struct imglist *list; > > LIST_FOREACH(img, &software->images, next) { > if (img->fname[0]) { > @@ -447,22 +480,19 @@ void cleanup_files(struct swupdate_cfg *software) { > LIST_REMOVE(img, next); > free(img); > } > - LIST_FOREACH(img, &software->scripts, next) { > - if (img->fname[0]) { > - if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdirscripts(), > - img->fname) >= (int)sizeof(fn)) { > - ERROR("Path too long: %s%s", get_tmpdirscripts(), img->fname); > - } > - remove_sw_file(fn); > - if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdir(), > - img->fname) >= (int)sizeof(fn)) { > - ERROR("Path too long: %s%s", TMPDIR, img->fname); > - } > - remove_sw_file(fn); > + > + for (count = 0; count < 2; count++) { > + if (count == 0) > + list = &software->scripts; > + else > + list = &software->bootscripts; Array? > + > + LIST_FOREACH(img, list, next) { > + cleaup_img_entry(img); > + > + LIST_REMOVE(img, next); > + free(img); > } > - dict_drop_db(&img->properties); > - LIST_REMOVE(img, next); > - free(img); > } > > dict_drop_db(&software->bootloader); > diff --git a/corelib/stream_interface.c b/corelib/stream_interface.c > index a200d7e..99b8329 100644 > --- a/corelib/stream_interface.c > +++ b/corelib/stream_interface.c > @@ -186,20 +186,38 @@ static int extract_files(int fd, struct swupdate_cfg *software) > break; > } > > - skip = check_if_required(&software->images, &fdh, > + int i; > + > + for (i = 0; i < 3; i++) { > + switch(i) { > + case 0: > + skip = check_if_required(&software->images, &fdh, > &software->installed_sw_list, > get_tmpdir(), > &img); > - if (skip == SKIP_FILE) { > + break; > /* > * Check for script, but scripts are not checked > * for version > */ > - skip = check_if_required(&software->scripts, &fdh, > + case 1: > + skip = check_if_required(&software->scripts, &fdh, > + NULL, > + get_tmpdir(), > + &img); > + break; > + case 2: > + skip = check_if_required(&software->bootscripts, &fdh, > NULL, > get_tmpdir(), > &img); > + break; > + } Array? > + > + if (skip != SKIP_FILE) > + break; > } > + > TRACE("Found file:\n\tfilename %s\n\tsize %u %s", > fdh.filename, > (unsigned int)fdh.size, [snip] Best regards Stefan
Hi Stefan, On 12/01/2018 20:34, Stefan Herbrechtsmeier wrote: > Hi Stefano, > > Am 12.01.2018 um 17:40 schrieb Stefano Babic: >> commit ff12cd69445c0f49d44ad0b75dea6f6ec1b0e449 forbids to use a >> bootloader >> script in the "images" section of sw-description. This avoids to set >> bootloader's >> variables in the middle of an installation that can brick the device. >> However, having a script is often much more comfortable as a list of >> couple >> <name, value> inside sw-description. This allows again to have >> bootloader scripts, >> but they must be inserted in the "bootenv" section of sw-description. > > What is the different between a script and a bootloader script? > A regular script in SWupdate is a shell or LUA script. A bootloader script is not an executable file, but in sense of U-Boot's introduced scripts (I know, I am guilty for this nomenclature because I introduced this in U-Boot). A bootloader script is just a file with coules <name> <value> entries, like: alpha 1 beta 2 gamma 3 A such file can be interpreted by u-boot's environment utility fw_setenv if the parmeter "-s" is passed. SWUpdate integrates this functionality and it is extended for other bootloader, too. A bootscript can be for U-Boot or GRUB (and now for EFIBootGuard). >> Signed-off-by: Stefano Babic <sbabic@denx.de> >> --- >> core/parser.c | 2 + >> corelib/installer.c | 108 >> +++++++++++++++++++++++++++++---------------- >> corelib/stream_interface.c | 24 ++++++++-- >> include/installer.h | 1 - >> include/swupdate.h | 1 + >> parser/parser.c | 44 +++++++++++++----- >> 6 files changed, 126 insertions(+), 54 deletions(-) >> >> diff --git a/core/parser.c b/core/parser.c >> index a1232bd..cdfbea8 100644 >> --- a/core/parser.c >> +++ b/core/parser.c >> @@ -147,6 +147,8 @@ int parse(struct swupdate_cfg *sw, const char >> *descfile) >> "images / files"); >> ret |= check_handler_list(&sw->partitions, PARTITION_HANDLER, >> "partitions"); >> + ret |= check_handler_list(&sw->bootscripts, BOOTLOADER_HANDLER, >> + "bootloader"); >> if (ret) >> return -EINVAL; >> diff --git a/corelib/installer.c b/corelib/installer.c >> index fc3011e..9a67399 100644 >> --- a/corelib/installer.c >> +++ b/corelib/installer.c >> @@ -233,6 +233,27 @@ static int prepare_boot_script(struct >> swupdate_cfg *cfg, const char *script) >> return ret; >> } >> +static int run_prepost_scripts(struct imglist *list, script_fn type) >> +{ >> + int ret; >> + struct img_type *img; >> + struct installer_handler *hnd; >> + >> + /* Scripts must be run before installing images */ >> + LIST_FOREACH(img, list, next) { >> + if (!img->is_script) >> + continue; >> + hnd = find_handler(img); >> + if (hnd) { >> + ret = hnd->installer(img, &type); >> + if (ret) >> + return ret; >> + } >> + } >> + >> + return 0; >> +} >> + >> static int update_bootloader_env(void) >> { >> int ret = 0; >> @@ -291,13 +312,14 @@ int install_images(struct swupdate_cfg *sw, int >> fdsw, int fromfile) >> /* Extract all scripts, preinstall scripts must be run now */ >> const char* tmpdir_scripts = get_tmpdirscripts(); >> ret = extract_scripts(fdsw, &sw->scripts, fromfile); >> + ret |= extract_scripts(fdsw, &sw->bootscripts, fromfile); >> if (ret) { >> ERROR("extracting script to %s failed", tmpdir_scripts); >> return ret; >> } >> /* Scripts must be run before installing images */ >> - ret = run_prepost_scripts(sw, PREINSTALL); >> + ret = run_prepost_scripts(&sw->scripts, PREINSTALL); >> if (ret) { >> ERROR("execute preinstall scripts failed"); >> return ret; >> @@ -388,7 +410,7 @@ int install_images(struct swupdate_cfg *sw, int >> fdsw, int fromfile) >> } >> - ret = run_prepost_scripts(sw, POSTINSTALL); >> + ret = run_prepost_scripts(&sw->scripts, POSTINSTALL); >> if (ret) { >> ERROR("execute postinstall scripts failed"); >> return ret; >> @@ -397,31 +419,11 @@ int install_images(struct swupdate_cfg *sw, int >> fdsw, int fromfile) >> if (!LIST_EMPTY(&sw->bootloader)) >> ret = update_bootloader_env(); >> - return ret; >> -} >> - >> -int run_prepost_scripts(struct swupdate_cfg *sw, script_fn type) >> -{ >> - int ret; >> - struct img_type *img; >> - struct installer_handler *hnd; >> - >> - /* Scripts must be run before installing images */ >> - LIST_FOREACH(img, &sw->scripts, next) { >> - if (!img->is_script) >> - continue; >> - hnd = find_handler(img); >> - if (hnd) { >> - ret = hnd->installer(img, &type); >> - if (ret) >> - return ret; >> - } >> - } >> + ret |= run_prepost_scripts(&sw->bootscripts, POSTINSTALL); >> - return 0; >> + return ret; >> } >> - >> static void remove_sw_file(char __attribute__ ((__unused__)) *fname) >> { >> #ifndef CONFIG_NOCLEANUP >> @@ -430,11 +432,42 @@ static void remove_sw_file(char __attribute__ >> ((__unused__)) *fname) >> #endif >> } >> +static void cleaup_img_entry(struct img_type *img) >> +{ >> + char *fn; >> + int i; >> + const char *tmp; >> + >> + if (img->fname[0]) { >> + >> + for (i = 0; i < 2; i++) { >> + switch(i) { >> + case 0: >> + tmp = get_tmpdirscripts(); >> + break; >> + case 1: >> + tmp = get_tmpdir(); >> + break; >> + } > > Maybe you could replace the switch by an array and use the ARRAY_SIZE > instead of the fix number: > const char *tmp[] = {get_tmpdirscripts(), get_tmpdir()} I'll do in V2, thanks. > >> + >> + if (asprintf(&fn, "%s%s", tmp, img->fname) == >> ENOMEM_ASPRINTF) { >> + ERROR("Path too long: %s%s", tmp, img->fname); >> + } else { >> + remove_sw_file(fn); >> + free(fn); >> + } >> + } >> + } >> + dict_drop_db(&img->properties); >> +} >> + >> void cleanup_files(struct swupdate_cfg *software) { >> char fn[64]; >> struct img_type *img; >> struct hw_type *hw; >> const char* TMPDIR = get_tmpdir(); >> + int count; >> + struct imglist *list; >> LIST_FOREACH(img, &software->images, next) { >> if (img->fname[0]) { >> @@ -447,22 +480,19 @@ void cleanup_files(struct swupdate_cfg *software) { >> LIST_REMOVE(img, next); >> free(img); >> } >> - LIST_FOREACH(img, &software->scripts, next) { >> - if (img->fname[0]) { >> - if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdirscripts(), >> - img->fname) >= (int)sizeof(fn)) { >> - ERROR("Path too long: %s%s", get_tmpdirscripts(), >> img->fname); >> - } >> - remove_sw_file(fn); >> - if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdir(), >> - img->fname) >= (int)sizeof(fn)) { >> - ERROR("Path too long: %s%s", TMPDIR, img->fname); >> - } >> - remove_sw_file(fn); >> + >> + for (count = 0; count < 2; count++) { >> + if (count == 0) >> + list = &software->scripts; >> + else >> + list = &software->bootscripts; > > Array? > >> + >> + LIST_FOREACH(img, list, next) { >> + cleaup_img_entry(img); >> + >> + LIST_REMOVE(img, next); >> + free(img); >> } >> - dict_drop_db(&img->properties); >> - LIST_REMOVE(img, next); >> - free(img); >> } >> dict_drop_db(&software->bootloader); >> diff --git a/corelib/stream_interface.c b/corelib/stream_interface.c >> index a200d7e..99b8329 100644 >> --- a/corelib/stream_interface.c >> +++ b/corelib/stream_interface.c >> @@ -186,20 +186,38 @@ static int extract_files(int fd, struct >> swupdate_cfg *software) >> break; >> } >> - skip = check_if_required(&software->images, &fdh, >> + int i; >> + >> + for (i = 0; i < 3; i++) { >> + switch(i) { >> + case 0: >> + skip = check_if_required(&software->images, &fdh, >> &software->installed_sw_list, >> get_tmpdir(), >> &img); >> - if (skip == SKIP_FILE) { >> + break; >> /* >> * Check for script, but scripts are not checked >> * for version >> */ >> - skip = check_if_required(&software->scripts, &fdh, >> + case 1: >> + skip = check_if_required(&software->scripts, &fdh, >> + NULL, >> + get_tmpdir(), >> + &img); >> + break; >> + case 2: >> + skip = check_if_required(&software->bootscripts, >> &fdh, >> NULL, >> get_tmpdir(), >> &img); >> + break; >> + } > > Array? > >> + >> + if (skip != SKIP_FILE) >> + break; >> } >> + >> TRACE("Found file:\n\tfilename %s\n\tsize %u %s", >> fdh.filename, >> (unsigned int)fdh.size, > > [snip] > > Best regards > Stefan > Best regards, Stefano Babic -- ===================================================================== DENX Software Engineering GmbH, Managing Director: Wolfgang Denk HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany Phone: +49-8142-66989-53 Fax: +49-8142-66989-80 Email: sbabic@denx.de =====================================================================
diff --git a/core/parser.c b/core/parser.c index a1232bd..cdfbea8 100644 --- a/core/parser.c +++ b/core/parser.c @@ -147,6 +147,8 @@ int parse(struct swupdate_cfg *sw, const char *descfile) "images / files"); ret |= check_handler_list(&sw->partitions, PARTITION_HANDLER, "partitions"); + ret |= check_handler_list(&sw->bootscripts, BOOTLOADER_HANDLER, + "bootloader"); if (ret) return -EINVAL; diff --git a/corelib/installer.c b/corelib/installer.c index fc3011e..9a67399 100644 --- a/corelib/installer.c +++ b/corelib/installer.c @@ -233,6 +233,27 @@ static int prepare_boot_script(struct swupdate_cfg *cfg, const char *script) return ret; } +static int run_prepost_scripts(struct imglist *list, script_fn type) +{ + int ret; + struct img_type *img; + struct installer_handler *hnd; + + /* Scripts must be run before installing images */ + LIST_FOREACH(img, list, next) { + if (!img->is_script) + continue; + hnd = find_handler(img); + if (hnd) { + ret = hnd->installer(img, &type); + if (ret) + return ret; + } + } + + return 0; +} + static int update_bootloader_env(void) { int ret = 0; @@ -291,13 +312,14 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile) /* Extract all scripts, preinstall scripts must be run now */ const char* tmpdir_scripts = get_tmpdirscripts(); ret = extract_scripts(fdsw, &sw->scripts, fromfile); + ret |= extract_scripts(fdsw, &sw->bootscripts, fromfile); if (ret) { ERROR("extracting script to %s failed", tmpdir_scripts); return ret; } /* Scripts must be run before installing images */ - ret = run_prepost_scripts(sw, PREINSTALL); + ret = run_prepost_scripts(&sw->scripts, PREINSTALL); if (ret) { ERROR("execute preinstall scripts failed"); return ret; @@ -388,7 +410,7 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile) } - ret = run_prepost_scripts(sw, POSTINSTALL); + ret = run_prepost_scripts(&sw->scripts, POSTINSTALL); if (ret) { ERROR("execute postinstall scripts failed"); return ret; @@ -397,31 +419,11 @@ int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile) if (!LIST_EMPTY(&sw->bootloader)) ret = update_bootloader_env(); - return ret; -} - -int run_prepost_scripts(struct swupdate_cfg *sw, script_fn type) -{ - int ret; - struct img_type *img; - struct installer_handler *hnd; - - /* Scripts must be run before installing images */ - LIST_FOREACH(img, &sw->scripts, next) { - if (!img->is_script) - continue; - hnd = find_handler(img); - if (hnd) { - ret = hnd->installer(img, &type); - if (ret) - return ret; - } - } + ret |= run_prepost_scripts(&sw->bootscripts, POSTINSTALL); - return 0; + return ret; } - static void remove_sw_file(char __attribute__ ((__unused__)) *fname) { #ifndef CONFIG_NOCLEANUP @@ -430,11 +432,42 @@ static void remove_sw_file(char __attribute__ ((__unused__)) *fname) #endif } +static void cleaup_img_entry(struct img_type *img) +{ + char *fn; + int i; + const char *tmp; + + if (img->fname[0]) { + + for (i = 0; i < 2; i++) { + switch(i) { + case 0: + tmp = get_tmpdirscripts(); + break; + case 1: + tmp = get_tmpdir(); + break; + } + + if (asprintf(&fn, "%s%s", tmp, img->fname) == ENOMEM_ASPRINTF) { + ERROR("Path too long: %s%s", tmp, img->fname); + } else { + remove_sw_file(fn); + free(fn); + } + } + } + dict_drop_db(&img->properties); +} + void cleanup_files(struct swupdate_cfg *software) { char fn[64]; struct img_type *img; struct hw_type *hw; const char* TMPDIR = get_tmpdir(); + int count; + struct imglist *list; LIST_FOREACH(img, &software->images, next) { if (img->fname[0]) { @@ -447,22 +480,19 @@ void cleanup_files(struct swupdate_cfg *software) { LIST_REMOVE(img, next); free(img); } - LIST_FOREACH(img, &software->scripts, next) { - if (img->fname[0]) { - if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdirscripts(), - img->fname) >= (int)sizeof(fn)) { - ERROR("Path too long: %s%s", get_tmpdirscripts(), img->fname); - } - remove_sw_file(fn); - if (snprintf(fn, sizeof(fn), "%s%s", get_tmpdir(), - img->fname) >= (int)sizeof(fn)) { - ERROR("Path too long: %s%s", TMPDIR, img->fname); - } - remove_sw_file(fn); + + for (count = 0; count < 2; count++) { + if (count == 0) + list = &software->scripts; + else + list = &software->bootscripts; + + LIST_FOREACH(img, list, next) { + cleaup_img_entry(img); + + LIST_REMOVE(img, next); + free(img); } - dict_drop_db(&img->properties); - LIST_REMOVE(img, next); - free(img); } dict_drop_db(&software->bootloader); diff --git a/corelib/stream_interface.c b/corelib/stream_interface.c index a200d7e..99b8329 100644 --- a/corelib/stream_interface.c +++ b/corelib/stream_interface.c @@ -186,20 +186,38 @@ static int extract_files(int fd, struct swupdate_cfg *software) break; } - skip = check_if_required(&software->images, &fdh, + int i; + + for (i = 0; i < 3; i++) { + switch(i) { + case 0: + skip = check_if_required(&software->images, &fdh, &software->installed_sw_list, get_tmpdir(), &img); - if (skip == SKIP_FILE) { + break; /* * Check for script, but scripts are not checked * for version */ - skip = check_if_required(&software->scripts, &fdh, + case 1: + skip = check_if_required(&software->scripts, &fdh, + NULL, + get_tmpdir(), + &img); + break; + case 2: + skip = check_if_required(&software->bootscripts, &fdh, NULL, get_tmpdir(), &img); + break; + } + + if (skip != SKIP_FILE) + break; } + TRACE("Found file:\n\tfilename %s\n\tsize %u %s", fdh.filename, (unsigned int)fdh.size, diff --git a/include/installer.h b/include/installer.h index 658b064..c0fe5e5 100644 --- a/include/installer.h +++ b/include/installer.h @@ -31,7 +31,6 @@ int check_if_required(struct imglist *list, struct filehdr *pfdh, struct img_type **pimg); int install_images(struct swupdate_cfg *sw, int fdsw, int fromfile); int install_single_image(struct img_type *img); -int run_prepost_scripts(struct swupdate_cfg *sw, script_fn type); int postupdate(struct swupdate_cfg *swcfg, const char *info); void cleanup_files(struct swupdate_cfg *software); diff --git a/include/swupdate.h b/include/swupdate.h index b065f7e..2cc824d 100644 --- a/include/swupdate.h +++ b/include/swupdate.h @@ -134,6 +134,7 @@ struct swupdate_cfg { struct imglist images; struct imglist partitions; struct imglist scripts; + struct imglist bootscripts; struct dictlist bootloader; struct proclist extprocs; void *dgst; /* Structure for signed images */ diff --git a/parser/parser.c b/parser/parser.c index 84b6576..9cd4204 100644 --- a/parser/parser.c +++ b/parser/parser.c @@ -351,6 +351,7 @@ static int parse_bootloader(parsertype p, void *cfg, struct swupdate_cfg *swcfg) { void *setting, *elem; int count, i; + struct img_type *script; char name[32]; char value[255]; @@ -372,24 +373,45 @@ static int parse_bootloader(parsertype p, void *cfg, struct swupdate_cfg *swcfg) /* * Check for mandatory field */ - if(!(exist_field_string(p, elem, "name"))) { - TRACE("bootloader entry without variable name field, skipping.."); + if(exist_field_string(p, elem, "name")) { + /* + * Call directly get_field_string with size 0 + * to let allocate the place for the strings + */ + GET_FIELD_STRING(p, elem, "name", name); + GET_FIELD_STRING(p, elem, "value", value); + dict_set_value(&swcfg->bootloader, name, value); + TRACE("Bootloader var: %s = %s\n", + name, + dict_get_value(&swcfg->bootloader, name)); continue; } - /* - * Call directly get_field_string with size 0 - * to let allocate the place for the strings + * Check if it is a bootloader script */ - GET_FIELD_STRING(p, elem, "name", name); - GET_FIELD_STRING(p, elem, "value", value); - dict_set_value(&swcfg->bootloader, name, value); + if(!(exist_field_string(p, elem, "filename"))) { + TRACE("bootloader entry is neither a script nor name/value."); + continue; + } + script = (struct img_type *)calloc(1, sizeof(struct img_type)); + if (!script) { + ERROR( "No memory: malloc failed\n"); + return -ENOMEM; + } + GET_FIELD_STRING(p, elem, "filename", script->fname); + GET_FIELD_STRING(p, elem, "type", script->type); + GET_FIELD_STRING(p, elem, "data", script->type_data); + get_hash_value(p, elem, script->sha256); + get_field(p, elem, "encrypted", &script->is_encrypted); + get_field(p, elem, "compressed", &script->compressed); + get_field(p, elem, "encrypted", &script->is_encrypted); + script->is_script = 1; - TRACE("Bootloader var: %s = %s\n", - name, - dict_get_value(&swcfg->bootloader, name)); + LIST_INSERT_HEAD(&swcfg->bootscripts, script, next); + TRACE("Found U-Boot Script: %s\n", + script->fname); } return 0;
commit ff12cd69445c0f49d44ad0b75dea6f6ec1b0e449 forbids to use a bootloader script in the "images" section of sw-description. This avoids to set bootloader's variables in the middle of an installation that can brick the device. However, having a script is often much more comfortable as a list of couple <name, value> inside sw-description. This allows again to have bootloader scripts, but they must be inserted in the "bootenv" section of sw-description. Signed-off-by: Stefano Babic <sbabic@denx.de> --- core/parser.c | 2 + corelib/installer.c | 108 +++++++++++++++++++++++++++++---------------- corelib/stream_interface.c | 24 ++++++++-- include/installer.h | 1 - include/swupdate.h | 1 + parser/parser.c | 44 +++++++++++++----- 6 files changed, 126 insertions(+), 54 deletions(-)