diff options
-rw-r--r-- | include/tpax/tpax.h | 4 | ||||
-rw-r--r-- | include/tpax/tpax_specs.h | 4 | ||||
-rw-r--r-- | src/internal/tpax_driver_impl.h | 74 | ||||
-rw-r--r-- | src/logic/tpax_archive_append.c | 69 |
4 files changed, 146 insertions, 5 deletions
diff --git a/include/tpax/tpax.h b/include/tpax/tpax.h index 9e9fa38..8897818 100644 --- a/include/tpax/tpax.h +++ b/include/tpax/tpax.h @@ -119,6 +119,7 @@ struct tpax_driver_ctx { const char * module; const struct tpax_common_ctx * cctx; struct tpax_error_info ** errv; + const off_t * cpos; void * any; }; @@ -128,6 +129,8 @@ struct tpax_unit_ctx { const struct tpax_ustar_header *uhdr; const struct tpax_cpio_header * chdr; const struct stat * st; + const off_t * hpos; + const off_t * dpos; void * any; }; @@ -148,6 +151,7 @@ tpax_api int tpax_set_driver_fdctx (struct tpax_driver_ctx *, const struct /* core api */ tpax_api int tpax_archive_append (const struct tpax_driver_ctx *, const struct tpax_unit_ctx *); +tpax_api int tpax_archive_seal (const struct tpax_driver_ctx *); /* helper api */ tpax_api int tpax_path_copy (char *, const char *, size_t, uint32_t, size_t *); diff --git a/include/tpax/tpax_specs.h b/include/tpax/tpax_specs.h index d0ac5a4..e30b36b 100644 --- a/include/tpax/tpax_specs.h +++ b/include/tpax/tpax_specs.h @@ -5,6 +5,10 @@ extern "C" { #endif +#define TPAX_PAX_BLOCK_SIZE 5120 +#define TPAX_CPIO_BLOCK_SIZE 5120 +#define TPAX_USTAR_BLOCK_SIZE 10240 + #define TPAX_USTAR_MAGIC {'u','s','t','a','r',0} #define TPAX_USTAR_VERSION {'0','0'} diff --git a/src/internal/tpax_driver_impl.h b/src/internal/tpax_driver_impl.h index 7e610d0..4003305 100644 --- a/src/internal/tpax_driver_impl.h +++ b/src/internal/tpax_driver_impl.h @@ -52,12 +52,15 @@ struct tpax_driver_ctx_impl { struct tpax_error_info erribuf[64]; void * bufaddr; size_t bufsize; + off_t cpos; }; struct tpax_unit_ctx_impl { const char * path; struct tpax_unit_ctx uctx; struct stat st; + off_t hpos; + off_t dpos; const char * link; char linkbuf[1024]; union { @@ -80,6 +83,17 @@ static inline struct tpax_driver_ctx_impl * tpax_get_driver_ictx( return 0; } +static inline struct tpax_unit_ctx_impl * tpax_get_unit_ictx( + const struct tpax_unit_ctx * uctx) +{ + struct tpax_unit_ctx_impl * ictx; + uintptr_t addr; + + addr = (uintptr_t)uctx - offsetof(struct tpax_unit_ctx_impl,uctx); + ictx = (struct tpax_unit_ctx_impl *)addr; + return ictx; +} + static inline void * tpax_get_driver_anon_map_addr( const struct tpax_driver_ctx * dctx, size_t * size) @@ -143,4 +157,64 @@ static inline int tpax_driver_fddst(const struct tpax_driver_ctx * dctx) return fdctx.fddst; } +static inline off_t tpax_get_driver_cpos(const struct tpax_driver_ctx * dctx) +{ + struct tpax_driver_ctx_impl * ictx; + ictx = tpax_get_driver_ictx(dctx); + return ictx->cpos; +} + +static inline void tpax_set_driver_cpos(const struct tpax_driver_ctx * dctx, off_t cpos) +{ + struct tpax_driver_ctx_impl * ictx; + ictx = tpax_get_driver_ictx(dctx); + ictx->cpos = cpos; +} + +static inline off_t tpax_get_unit_hpos(const struct tpax_unit_ctx * uctx) +{ + struct tpax_unit_ctx_impl * ictx; + ictx = tpax_get_unit_ictx(uctx); + return ictx->hpos; +} + +static inline void tpax_set_unit_hpos(const struct tpax_unit_ctx * uctx, off_t hpos) +{ + struct tpax_unit_ctx_impl * ictx; + ictx = tpax_get_unit_ictx(uctx); + ictx->hpos = hpos; +} + +static inline off_t tpax_get_unit_dpos(const struct tpax_unit_ctx * uctx) +{ + struct tpax_unit_ctx_impl * ictx; + ictx = tpax_get_unit_ictx(uctx); + return ictx->dpos; +} + +static inline void tpax_set_unit_dpos(const struct tpax_unit_ctx * uctx, off_t dpos) +{ + struct tpax_unit_ctx_impl * ictx; + ictx = tpax_get_unit_ictx(uctx); + ictx->dpos = dpos; +} + +static inline ssize_t tpax_get_archive_block_size(const struct tpax_driver_ctx * dctx) +{ + if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_PAX) + return TPAX_PAX_BLOCK_SIZE; + + else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_CPIO) + return TPAX_CPIO_BLOCK_SIZE; + + else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_USTAR) + return TPAX_USTAR_BLOCK_SIZE; + + else if (dctx->cctx->drvflags & TPAX_DRIVER_WRITE_FORMAT_RUSTAR) + return TPAX_USTAR_BLOCK_SIZE; + + else + return 0; +} + #endif diff --git a/src/logic/tpax_archive_append.c b/src/logic/tpax_archive_append.c index ce357b5..dfdd92c 100644 --- a/src/logic/tpax_archive_append.c +++ b/src/logic/tpax_archive_append.c @@ -1,3 +1,4 @@ + /******************************************************/ /* tpax: a topological pax implementation */ /* Copyright (C) 2020 Z. Gilboa */ @@ -48,9 +49,12 @@ static int tpax_archive_append_memory_data( } static int tpax_archive_append_pad( - int fdout, - const struct stat * st) + const struct tpax_driver_ctx * dctx, + int fdout, + const struct stat * st) { + int ret; + off_t cpos; ssize_t nbytes; char buf[512]; @@ -62,8 +66,13 @@ static int tpax_archive_append_pad( memset(buf,0,nbytes); - return tpax_archive_append_memory_data( - fdout,buf,nbytes); + cpos = tpax_get_driver_cpos(dctx); + cpos += st->st_size + nbytes; + + if (!(ret = tpax_archive_append_memory_data(fdout,buf,nbytes))) + tpax_set_driver_cpos(dctx,cpos); + + return ret; } int tpax_archive_append( @@ -71,6 +80,8 @@ int tpax_archive_append( const struct tpax_unit_ctx * uctx) { struct tpax_ustar_header uhdr; + off_t hpos; + off_t dpos; int fdout; int fdtmp; ssize_t nread; @@ -89,6 +100,10 @@ int tpax_archive_append( /* driver */ fdout = tpax_driver_fdout(dctx); + /* header and data offsets: todo pax and cpio */ + hpos = tpax_get_driver_cpos(dctx); + dpos = hpos + sizeof(uhdr); + /* header */ if (tpax_init_ustar_header( dctx,*uctx->path,uctx->st, @@ -130,6 +145,8 @@ int tpax_archive_append( return TPAX_SYSTEM_ERROR(dctx); } + tpax_set_driver_cpos(dctx,dpos); + /* append data from snapshot */ if (fdtmp >= 0) { if (!buf) { @@ -170,5 +187,47 @@ int tpax_archive_append( } return tpax_archive_append_pad( - fdout,uctx->st); + dctx,fdout,uctx->st); +} + +int tpax_archive_seal(const struct tpax_driver_ctx * dctx) +{ + int fdout; + off_t cpos; + ssize_t nbytes; + ssize_t nwritten; + ssize_t blksize; + char buf[512]; + + blksize = tpax_get_archive_block_size(dctx); + cpos = tpax_get_driver_cpos(dctx); + + if (cpos % 512) + return TPAX_CUSTOM_ERROR(dctx,TPAX_ERR_FLOW_ERROR); + + fdout = tpax_driver_fdout(dctx); + memset(buf,0,sizeof(buf)); + + switch (cpos % blksize) { + case 0: + nbytes = cpos + blksize; + break; + + default: + nbytes = cpos / blksize; + nbytes *= blksize; + nbytes += blksize; + + if (nbytes-cpos == 512) + nbytes += blksize; + } + + for (nwritten=cpos; nwritten<nbytes; nwritten+=512) { + if (tpax_archive_append_memory_data(fdout,buf,512) < 0) + return TPAX_SYSTEM_ERROR(dctx); + + tpax_set_driver_cpos(dctx,nwritten); + } + + return 0; } |