Message ID | 1560958859-15547-3-git-send-email-philippe.reynes@softathome.com |
---|---|
State | Changes Requested |
Headers | show |
Series | add a new handler ubiswap to swap several ubi volume | expand |
Hi Philippe, On 19/06/19 17:40, Philippe Reynes wrote: > This new handler ubiswap swap the name of several ubi volume > in atomic way after all images were flashed. This handler is > seen as a script by swupdate, and all the date are provided > by the sw-description file. > > Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com> > --- > doc/source/handlers.rst | 18 +++++++ > handlers/ubivol_handler.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 141 insertions(+) > > diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst > index 03c0a69..f06a1d0 100644 > --- a/doc/source/handlers.rst > +++ b/doc/source/handlers.rst > @@ -163,6 +163,24 @@ However, please note the following limitations: > - Atomic renames are only possible and permitted for volumes residing > on the same UBI device. > > +There is a handler ubiswap that allow to do an atomic swap for several > +ubi volume after all the images were flashed. This handler is a script > +for the point of view of swudate, so the node that provide it the data > +should be added in the section scripts. > + > +:: > + > + scripts: ( > + { > + type = "ubiswap"; > + properties: { > + swap-0 = [ "boot" , " boot_r" ]; > + swap-1 = [ "kernel" , "kernel_r" ]; > + swap-2 = [ "rootfs" , "rootfs_r" ]; > + }, > + }, > + ); > + > > Lua Handlers > ------------ > diff --git a/handlers/ubivol_handler.c b/handlers/ubivol_handler.c > index 60851e5..a1cdce5 100644 > --- a/handlers/ubivol_handler.c > +++ b/handlers/ubivol_handler.c > @@ -373,6 +373,127 @@ static int adjust_volume(struct img_type *cfg, > return 0; > } > > +static int ubi_volume_get_info(char *name, int *dev_num, int *vol_id) > +{ > + struct ubi_part *ubi_part; > + > + ubi_part = search_volume_global(name); > + if (!ubi_part) { > + ERROR("could not found UBI volume %s", name); > + return -1; > + } > + > + *dev_num = ubi_part->vol_info.dev_num; > + *vol_id = ubi_part->vol_info.vol_id; > + > + return 0; > +} > + > +static int swap_volume(struct img_type *img, void *data) > +{ > + script_fn scriptfn; > + struct flash_description *flash = get_flash_info(); > + libubi_t libubi = flash->libubi; > + int num, count = 0; > + struct dict_list *volumes; > + struct dict_list_elem *volume; > + char *name[2]; > + int dev_num[2], vol_id[2], global_dev_num = -1; > + char prop[SWUPDATE_GENERAL_STRING_SIZE]; > + char masternode[UBI_MAX_VOLUME_NAME+1]; > + struct ubi_rnvol_req rnvol; > + int ret = -1; > + > + if (!data) > + return -EINVAL; > + > + scriptfn = *(script_fn *)data; > + > + /* > + * Call only in case of postinstall > + */ > + if (scriptfn != POSTINSTALL) > + return 0; > + > + while (1) { > + snprintf(prop, sizeof(prop), "swap-%d", count); > + volumes = dict_get_list(&img->properties, prop); > + if (!volumes) > + break; > + > + if (count >= (UBI_MAX_RNVOL / 2)) { > + ERROR("Too many requested swap"); > + goto out; > + } > + > + num = 0; > + LIST_FOREACH(volume, volumes, next) { > + if (num >= 2) { > + ERROR("Too many ubi volume (%s)", prop); > + goto out; > + } > + > + name[num] = volume->value; > + if (ubi_volume_get_info(volume->value, > + &dev_num[num], > + &vol_id[num]) < 0) > + goto out; > + > + num++; > + } > + > + if (num != 2) { > + ERROR("Invalid number (%d) of ubi volume (%s)", num, prop); > + goto out; > + } > + > + if (dev_num[0] != dev_num[1]) { > + ERROR("both volume should be on the same UBI device"); > + goto out; > + } > + > + if (global_dev_num == -1) { > + global_dev_num = dev_num[0]; > + snprintf(&masternode[0], sizeof(masternode), > + "/dev/ubi%d", global_dev_num); > + } else { > + if (global_dev_num != dev_num[0]) { > + ERROR("all volumes should be on the" > + "same UBI device (%s)", prop); > + goto out; > + } > + } > + > + TRACE("swap UBI volume %s <-> %s", name[0], name[1]); > + > + /* swap first -> second */ > + rnvol.ents[2 * count + 0].vol_id = vol_id[0]; > + rnvol.ents[2 * count + 0].name_len = strlen(name[1]); > + strcpy(rnvol.ents[2 * count + 0].name, name[1]); > + > + /* swap second -> first */ > + rnvol.ents[2 * count + 1].vol_id = vol_id[1]; > + rnvol.ents[2 * count + 1].name_len = strlen(name[0]); > + strcpy(rnvol.ents[2 * count + 1].name, name[0]); > + > + count++; > + } > + > + if (!count) { > + ERROR("No UBI volume provided"); > + goto out; > + } > + > + rnvol.count = count * 2; > + > + ret = ubi_rnvols(libubi, masternode, &rnvol); > + if (ret) > + ERROR("cannot swap UBI volume"); > + > + out: > + return ret; > +} > + > __attribute__((constructor)) > void ubi_handler(void) > { > @@ -380,4 +501,6 @@ void ubi_handler(void) > IMAGE_HANDLER, NULL); > register_handler("ubipartition", adjust_volume, > PARTITION_HANDLER, NULL); > + register_handler("ubiswap", swap_volume, > + SCRIPT_HANDLER, NULL); > } > Acked-by: Stefano Babic <sbabic@denx.de> Best regards, Stefano Babic
diff --git a/doc/source/handlers.rst b/doc/source/handlers.rst index 03c0a69..f06a1d0 100644 --- a/doc/source/handlers.rst +++ b/doc/source/handlers.rst @@ -163,6 +163,24 @@ However, please note the following limitations: - Atomic renames are only possible and permitted for volumes residing on the same UBI device. +There is a handler ubiswap that allow to do an atomic swap for several +ubi volume after all the images were flashed. This handler is a script +for the point of view of swudate, so the node that provide it the data +should be added in the section scripts. + +:: + + scripts: ( + { + type = "ubiswap"; + properties: { + swap-0 = [ "boot" , " boot_r" ]; + swap-1 = [ "kernel" , "kernel_r" ]; + swap-2 = [ "rootfs" , "rootfs_r" ]; + }, + }, + ); + Lua Handlers ------------ diff --git a/handlers/ubivol_handler.c b/handlers/ubivol_handler.c index 60851e5..a1cdce5 100644 --- a/handlers/ubivol_handler.c +++ b/handlers/ubivol_handler.c @@ -373,6 +373,127 @@ static int adjust_volume(struct img_type *cfg, return 0; } +static int ubi_volume_get_info(char *name, int *dev_num, int *vol_id) +{ + struct ubi_part *ubi_part; + + ubi_part = search_volume_global(name); + if (!ubi_part) { + ERROR("could not found UBI volume %s", name); + return -1; + } + + *dev_num = ubi_part->vol_info.dev_num; + *vol_id = ubi_part->vol_info.vol_id; + + return 0; +} + +static int swap_volume(struct img_type *img, void *data) +{ + script_fn scriptfn; + struct flash_description *flash = get_flash_info(); + libubi_t libubi = flash->libubi; + int num, count = 0; + struct dict_list *volumes; + struct dict_list_elem *volume; + char *name[2]; + int dev_num[2], vol_id[2], global_dev_num = -1; + char prop[SWUPDATE_GENERAL_STRING_SIZE]; + char masternode[UBI_MAX_VOLUME_NAME+1]; + struct ubi_rnvol_req rnvol; + int ret = -1; + + if (!data) + return -EINVAL; + + scriptfn = *(script_fn *)data; + + /* + * Call only in case of postinstall + */ + if (scriptfn != POSTINSTALL) + return 0; + + while (1) { + snprintf(prop, sizeof(prop), "swap-%d", count); + volumes = dict_get_list(&img->properties, prop); + if (!volumes) + break; + + if (count >= (UBI_MAX_RNVOL / 2)) { + ERROR("Too many requested swap"); + goto out; + } + + num = 0; + LIST_FOREACH(volume, volumes, next) { + if (num >= 2) { + ERROR("Too many ubi volume (%s)", prop); + goto out; + } + + name[num] = volume->value; + if (ubi_volume_get_info(volume->value, + &dev_num[num], + &vol_id[num]) < 0) + goto out; + + num++; + } + + if (num != 2) { + ERROR("Invalid number (%d) of ubi volume (%s)", num, prop); + goto out; + } + + if (dev_num[0] != dev_num[1]) { + ERROR("both volume should be on the same UBI device"); + goto out; + } + + if (global_dev_num == -1) { + global_dev_num = dev_num[0]; + snprintf(&masternode[0], sizeof(masternode), + "/dev/ubi%d", global_dev_num); + } else { + if (global_dev_num != dev_num[0]) { + ERROR("all volumes should be on the" + "same UBI device (%s)", prop); + goto out; + } + } + + TRACE("swap UBI volume %s <-> %s", name[0], name[1]); + + /* swap first -> second */ + rnvol.ents[2 * count + 0].vol_id = vol_id[0]; + rnvol.ents[2 * count + 0].name_len = strlen(name[1]); + strcpy(rnvol.ents[2 * count + 0].name, name[1]); + + /* swap second -> first */ + rnvol.ents[2 * count + 1].vol_id = vol_id[1]; + rnvol.ents[2 * count + 1].name_len = strlen(name[0]); + strcpy(rnvol.ents[2 * count + 1].name, name[0]); + + count++; + } + + if (!count) { + ERROR("No UBI volume provided"); + goto out; + } + + rnvol.count = count * 2; + + ret = ubi_rnvols(libubi, masternode, &rnvol); + if (ret) + ERROR("cannot swap UBI volume"); + + out: + return ret; +} + __attribute__((constructor)) void ubi_handler(void) { @@ -380,4 +501,6 @@ void ubi_handler(void) IMAGE_HANDLER, NULL); register_handler("ubipartition", adjust_volume, PARTITION_HANDLER, NULL); + register_handler("ubiswap", swap_volume, + SCRIPT_HANDLER, NULL); }
This new handler ubiswap swap the name of several ubi volume in atomic way after all images were flashed. This handler is seen as a script by swupdate, and all the date are provided by the sw-description file. Signed-off-by: Philippe Reynes <philippe.reynes@softathome.com> --- doc/source/handlers.rst | 18 +++++++ handlers/ubivol_handler.c | 123 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+)