-
Notifications
You must be signed in to change notification settings - Fork 59
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Introduce tarerofs for TurboOCI-apply
Currently erofs-utils is integrated into overlaybd by using `mkfs.erofs` executable file. It's not optimial since raw data needs to be dumped first and output data needs to be write into overlaybd then. Later API integration may be a better form but it needs more work. Signed-off-by: Hongzhen Luo <hongzhen.lhz@linux.alibaba.com>
- Loading branch information
Hongzhen Luo
committed
Mar 26, 2024
1 parent
0acf17f
commit b3e2cfc
Showing
3 changed files
with
178 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
#include "tarerofs.h" | ||
#include <stdio.h> | ||
#include <string.h> | ||
#include <sys/param.h> | ||
#include <sys/types.h> | ||
#include <sys/sysmacros.h> | ||
#include <fcntl.h> | ||
#include <errno.h> | ||
#include <stdlib.h> | ||
#include <unistd.h> | ||
#include <cstdio> | ||
#include <utime.h> | ||
#include <set> | ||
#include <string> | ||
#include <photon/fs/localfs.h> | ||
#include <photon/fs/path.h> | ||
#include <photon/common/string_view.h> | ||
#include <photon/fs/filesystem.h> | ||
#include <photon/common/alog.h> | ||
#include <photon/fs/fiemap.h> | ||
#include "../lsmt/file.h" | ||
#include "../lsmt/index.h" | ||
|
||
#define TAREROFS_BLOCK_SIZE 4096 | ||
#define __stringify(s) #s | ||
|
||
int TarErofs::extract_all() { | ||
ssize_t read; | ||
struct stat st; | ||
char buf[128*1024]; | ||
char base_path[64] = "/tmp/tarerofs_base_XXXXXX"; | ||
char command_line[256] = "mkfs.erofs --tar=0,upper.map,1073741824 -b" __stringify(TAREROFS_BLOCK_SIZE) " --aufs"; | ||
const char command_line2[] = " upper.erofs"; | ||
|
||
FILE *fp; | ||
photon::fs::IFile *rawfs = nullptr; | ||
int status; | ||
uint64_t blkaddr, toff; | ||
uint32_t nblocks; | ||
|
||
if (!meta_only) { | ||
LOG_ERROR("currently erofs supports fastoci mode only", strerror(errno)); | ||
return -1; | ||
} | ||
|
||
if (fs_base_file->fstat(&st)>= 0 && st.st_blocks > 0) { | ||
int fd = mkstemp(base_path); | ||
if (fd < 0) { | ||
LOG_ERROR("cannot generate a temporary file to dump overlaybd disk"); | ||
return -1; | ||
} | ||
std::strcat(command_line, " --base "); | ||
std::strcat(command_line, base_path); | ||
|
||
for (int i = 0; i < 800; i++) { | ||
read = fs_base_file->read(buf, sizeof(buf)); | ||
if (read != sizeof(buf) || | ||
write(fd, buf, read) != read) { | ||
read = -1; | ||
break; | ||
} | ||
} | ||
close(fd); | ||
if (read < 0) { | ||
return -1; | ||
} | ||
} | ||
std::strcat(command_line, command_line2); | ||
fp = popen(command_line, "w"); | ||
if (fp == NULL) { | ||
LOG_ERROR("failed to execute mkfs.erofs", strerror(errno)); | ||
return -1; | ||
} | ||
|
||
while ((read = file->read(buf, sizeof(buf))) > 0) { | ||
if (fwrite(buf, read, 1, fp) != 1) { | ||
read = -1; | ||
break; | ||
} | ||
} | ||
status = pclose(fp); | ||
|
||
if (read < 0 || status) { | ||
return -1; | ||
} | ||
rawfs = photon::fs::open_localfile_adaptor("upper.erofs", O_RDONLY, 0644); | ||
DEFER({ delete rawfs; }); | ||
|
||
/* write to LSMT */ | ||
fout->lseek(0, 0); | ||
while ((read = rawfs->read(buf, sizeof(buf))) > 0) { | ||
if (fout->write(buf, read) != read) { | ||
read = -1; | ||
break; | ||
} | ||
} | ||
|
||
/* write mapfile */ | ||
fp = fopen("upper.map", "r"); | ||
if (fp == NULL) { | ||
LOG_ERROR("unable to get upper.map, ignored"); | ||
return -1; | ||
} | ||
while (fscanf(fp, "%" PRIx64" %x %" PRIx64 "\n", &blkaddr, &nblocks, &toff) >= 3) { | ||
LSMT::RemoteMapping lba; | ||
lba.offset = blkaddr * TAREROFS_BLOCK_SIZE; | ||
lba.count = nblocks * TAREROFS_BLOCK_SIZE; | ||
lba.roffset = toff; | ||
int nwrite = fout->ioctl(LSMT::IFileRW::RemoteData, lba); | ||
if ((unsigned) nwrite != lba.count) { | ||
LOG_ERRNO_RETURN(0, -1, "failed to write lba"); | ||
} | ||
} | ||
fclose(fp); | ||
return 0; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#pragma once | ||
|
||
#include <sys/types.h> | ||
#include <sys/stat.h> | ||
#include <tar.h> | ||
#include <stdio.h> | ||
#include <stdlib.h> | ||
#include <sys/param.h> | ||
#include <pwd.h> | ||
#include <grp.h> | ||
#include <string.h> | ||
#include <photon/fs/filesystem.h> | ||
#include <photon/fs/fiemap.h> | ||
#include <photon/common/string_view.h> | ||
#include <set> | ||
#include <vector> | ||
#include <string> | ||
#include <list> | ||
#include <map> | ||
|
||
class TarErofs { | ||
public: | ||
TarErofs(photon::fs::IFile *file, photon::fs::IFile *target, uint64_t fs_blocksize = 4096, | ||
photon::fs::IFile *bf = nullptr, bool meta_only = true) | ||
: file(file), fout(target), fs_base_file(bf), meta_only(meta_only) {} | ||
|
||
int extract_all(); | ||
|
||
private: | ||
photon::fs::IFile *file = nullptr; // source | ||
photon::fs::IFile *fout = nullptr; // target | ||
photon::fs::IFile *fs_base_file = nullptr; | ||
bool meta_only; | ||
std::set<std::string> unpackedPaths; | ||
std::list<std::pair<std::string, int>> dirs; // <path, utime> | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters