[dpdk-dev] [PATCH v1 04/10] app/test: support resources archived by tar

2016-05-12 Thread Thomas Monjalon
2016-05-12 17:26, Thomas Monjalon:
> 2016-05-06 12:48, Jan Viktorin:
> > +$(eval $(call resource,test_resource_tar,resource.tar))
> 
> This tar resource is not provided. Should it be created in the Makefile?

Sorry I was looking at v1 while it is implemented in v2.


[dpdk-dev] [PATCH v1 04/10] app/test: support resources archived by tar

2016-05-12 Thread Thomas Monjalon
2016-05-06 12:48, Jan Viktorin:
> When needing a more complex resource (a file hierarchy), packing every single
> file as a single resource would be very ineffective. For that purpose, it is
> possible to pack the files into a tar archive, extract it before test from the
> resource and finally clean up all the created files.
> 
> This patch introduces functions resource_untar and resource_rm_by_tar to
> perform those tasks. An example of using those functions is included as a 
> test.
> 
> Signed-off-by: Jan Viktorin 
> ---
>  app/test/Makefile|   4 ++
>  app/test/resource.c  | 180 
> +++
>  app/test/resource.h  |  13 
>  app/test/test_resource.c |  29 
>  4 files changed, 226 insertions(+)
> 
> diff --git a/app/test/Makefile b/app/test/Makefile
> index a9502f1..90acd63 100644
> --- a/app/test/Makefile
> +++ b/app/test/Makefile
> @@ -77,6 +77,9 @@ SRCS-y += test.c
>  SRCS-y += resource.c
>  SRCS-y += test_resource.c
>  $(eval $(call resource,test_resource_c,resource.c))
> +$(eval $(call resource,test_resource_tar,resource.tar))

This tar resource is not provided. Should it be created in the Makefile?


[dpdk-dev] [PATCH v1 04/10] app/test: support resources archived by tar

2016-05-06 Thread Jan Viktorin
When needing a more complex resource (a file hierarchy), packing every single
file as a single resource would be very ineffective. For that purpose, it is
possible to pack the files into a tar archive, extract it before test from the
resource and finally clean up all the created files.

This patch introduces functions resource_untar and resource_rm_by_tar to
perform those tasks. An example of using those functions is included as a test.

Signed-off-by: Jan Viktorin 
---
 app/test/Makefile|   4 ++
 app/test/resource.c  | 180 +++
 app/test/resource.h  |  13 
 app/test/test_resource.c |  29 
 4 files changed, 226 insertions(+)

diff --git a/app/test/Makefile b/app/test/Makefile
index a9502f1..90acd63 100644
--- a/app/test/Makefile
+++ b/app/test/Makefile
@@ -77,6 +77,9 @@ SRCS-y += test.c
 SRCS-y += resource.c
 SRCS-y += test_resource.c
 $(eval $(call resource,test_resource_c,resource.c))
+$(eval $(call resource,test_resource_tar,resource.tar))
+resource.tar: test_resource.c
+   tar -C $(dir $<) -cf $@ $(notdir $<)
 SRCS-y += test_pci.c
 SRCS-y += test_prefetch.c
 SRCS-y += test_byteorder.c
@@ -196,6 +199,7 @@ CFLAGS += $(WERROR_FLAGS)
 CFLAGS += -D_GNU_SOURCE

 LDLIBS += -lm
+LDLIBS += -larchive

 # Disable VTA for memcpy test
 ifeq ($(CC), gcc)
diff --git a/app/test/resource.c b/app/test/resource.c
index a11c86e..7732bc7 100644
--- a/app/test/resource.c
+++ b/app/test/resource.c
@@ -33,6 +33,8 @@

 #include 
 #include 
+#include 
+#include 
 #include 
 #include 

@@ -90,6 +92,184 @@ int resource_fwrite_file(const struct resource *r, const 
char *fname)
return ret;
 }

+static int do_copy(struct archive *r, struct archive *w)
+{
+   const void *buf;
+   size_t len;
+   off_t off;
+   int ret;
+
+   while (1) {
+   ret = archive_read_data_block(r, , , );
+   if (ret == ARCHIVE_RETRY)
+   continue;
+
+   if (ret == ARCHIVE_EOF)
+   return 0;
+
+   if (ret != ARCHIVE_OK)
+   return ret;
+
+   do {
+   ret = archive_write_data_block(w, buf, len, off);
+   if (ret != ARCHIVE_OK && ret != ARCHIVE_RETRY)
+   return ret;
+   } while (ret != ARCHIVE_OK);
+   }
+}
+
+int resource_untar(const struct resource *res)
+{
+   struct archive *r;
+   struct archive *w;
+   struct archive_entry *e;
+   void *p;
+   int flags = 0;
+   int ret;
+
+   p = malloc(resource_size(res));
+   if (p == NULL)
+   rte_panic("Failed to malloc %zu B\n", resource_size(res));
+
+   memcpy(p, res->beg, resource_size(res));
+
+   r = archive_read_new();
+   if (r == NULL) {
+   free(p);
+   return -1;
+   }
+
+   archive_read_support_format_all(r);
+   archive_read_support_filter_all(r);
+
+   w = archive_write_disk_new();
+   if (w == NULL) {
+   archive_read_free(r);
+   free(p);
+   return -1;
+   }
+
+   flags |= ARCHIVE_EXTRACT_PERM;
+   flags |= ARCHIVE_EXTRACT_FFLAGS;
+   archive_write_disk_set_options(w, flags);
+   archive_write_disk_set_standard_lookup(w);
+
+   ret = archive_read_open_memory(r, p, resource_size(res));
+   if (ret != ARCHIVE_OK)
+   goto fail;
+
+   while (1) {
+   ret = archive_read_next_header(r, );
+   if (ret == ARCHIVE_EOF)
+   break;
+   if (ret != ARCHIVE_OK)
+   goto fail;
+
+   ret = archive_write_header(w, e);
+   if (ret == ARCHIVE_EOF)
+   break;
+   if (ret != ARCHIVE_OK)
+   goto fail;
+
+   if (archive_entry_size(e) == 0)
+   continue;
+
+   ret = do_copy(r, w);
+   if (ret != ARCHIVE_OK)
+   goto fail;
+
+   ret = archive_write_finish_entry(w);
+   if (ret != ARCHIVE_OK)
+   goto fail;
+   }
+
+   archive_write_free(w);
+   archive_read_free(r);
+   free(p);
+   return 0;
+
+fail:
+   archive_write_free(w);
+   archive_read_free(r);
+   free(p);
+   rte_panic("Failed: %s\n", archive_error_string(r));
+   return -1;
+}
+
+int resource_rm_by_tar(const struct resource *res)
+{
+   struct archive *r;
+   struct archive_entry *e;
+   void *p;
+   int try_again = 1;
+   int ret;
+
+   p = malloc(resource_size(res));
+   if (p == NULL)
+   rte_panic("Failed to malloc %zu B\n", resource_size(res));
+
+   memcpy(p, res->beg, resource_size(res));
+
+   while (try_again) {
+   r = archive_read_new();
+   if (r == NULL) {
+   free(p);
+