Skip to content
This repository has been archived by the owner on Oct 2, 2024. It is now read-only.

ch-run: run SIF files #1928

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions bin/ch-run.c
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,10 @@ int main(int argc, char *argv[])
Tf (!args.c.writable || args.unsafe,
"--write invalid when running by name");
break;
case IMG_SIF:
INFO("SIF file detected!");
//args.c.newroot = realpath_(args.c.img_ref, false);
break;
case IMG_SQUASH:
#ifndef HAVE_LIBSQUASHFUSE
FATAL(0, "this ch-run does not support internal SquashFS mounts");
Expand Down
30 changes: 27 additions & 3 deletions bin/ch_core.c
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ void containerize(struct container *c)
// reduce the number of code paths.
setup_namespaces(c, geteuid(), 0, getegid(), 0);
#ifdef HAVE_LIBSQUASHFUSE
if (c->type == IMG_SQUASH)
if ((c->type == IMG_SQUASH) || (c->type == IMG_SIF))
sq_fork(c);
#endif
setup_namespaces(c, 0, c->container_uid, 0, c->container_gid);
Expand Down Expand Up @@ -391,6 +391,7 @@ enum img_type image_type(const char *ref, const char *storage_dir)
struct stat st;
FILE *fp;
char magic[4]; // four bytes, not a string
char header[42]; // thirty-two bytes for launch len and ten for magic len

// If there’s a directory in storage where we would expect there to be if
// ref were an image name, assume it really is an image name.
Expand All @@ -409,8 +410,7 @@ enum img_type image_type(const char *ref, const char *storage_dir)
fp = fopen(ref, "rb");
Tf (fp != NULL, "can't open: %s", ref);
Tf (fread(magic, sizeof(char), 4, fp) == 4, "can't read: %s", ref);
Zf (fclose(fp), "can't close: %s", ref);
VERBOSE("image file magic expected: 6873 7173; actual: %x%x %x%x",
VERBOSE("squash image file magic expected: 6873 7173; actual: %x%x %x%x",
magic[0], magic[1], magic[2], magic[3]);

// If magic number matches, it’s a squash. Note: Magic number is 6873 7173,
Expand All @@ -420,10 +420,34 @@ enum img_type image_type(const char *ref, const char *storage_dir)
if (memcmp(magic, "hsqs", 4) == 0)
return IMG_SQUASH;

// Check if it is a SIF file
// See: https://github.com/sylabs/sif/tree/main
// Parse header: skip launch constant and record magic value
fseek(fp, 0, SEEK_SET); // start from beginning of file
Tf (fread(header, sizeof(char), 32, fp) == 32, "can't read: %s", ref);
Tf (fread(header, 1, 10, fp) == 10, "can't read: %s", ref);
char *magic_val = to_string(header);
VERBOSE("sif file magic expected: SIF_MAGIC: actual: %s", magic_val);
if (strcmp(magic_val, "SIF_MAGIC") == 0)
return IMG_SIF;

Zf (fclose(fp), "can't close: %s", ref);

// Well now we’re stumped.
FATAL(0, "unknown image type: %s", ref);
}

char *to_string(char *c)
{
char *str = malloc(strlen(c) + 1);
if (str == NULL) {
perror("Failed to allocate memory");
exit(EXIT_FAILURE);
}
strcpy(str, c);
return str;
}

char *img_name2path(const char *name, const char *storage_dir)
{
char *path;
Expand Down
2 changes: 2 additions & 0 deletions bin/ch_core.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ struct bind {

enum img_type {
IMG_DIRECTORY, // normal directory, perhaps an external mount of some kind
IMG_SIF, // SIF file (squash portion not yet mounted)
IMG_SQUASH, // SquashFS archive file (not yet mounted)
IMG_NAME, // name of image in storage
IMG_NONE, // image type is not set yet
Expand Down Expand Up @@ -53,6 +54,7 @@ void containerize(struct container *c);
enum img_type image_type(const char *ref, const char *images_dir);
char *img_name2path(const char *name, const char *storage_dir);
void run_user_command(char *argv[], const char *initial_dir);
char *to_string(char *c);
#ifdef HAVE_SECCOMP
void seccomp_install(void);
#endif
35 changes: 34 additions & 1 deletion bin/ch_fuse.c
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,35 @@ int sq_loop(void)
return exit_code;
}

/* Find the byte offset of where the squash portion begins */
int sq_offset(const char *sif_path)
{
FILE *fp = fopen(sif_path, "rb");
char offset[8];
char magic[4];
int squash_offset = 0;
int i;

Tf (fp != NULL, "can't open: %s", sif_path);

// iterate through file in chunks of size eight until squash magic number appears
while (fread(offset,8,1,fp) != 0) {
for (i=0; i < 4; i++) {
magic[i] = offset[i];
}
if (memcmp(magic, "hsqs", 4) == 0) { // 6873 7173
// Squash byte offset is zero if IMG_SQUASH
// Squash byte offset is > zero if IMG_SIF
squash_offset = ftell(fp)-8;
VERBOSE("Squash byte offset: %d\n", squash_offset);
VERBOSE("Magic is: %x%x %x%x\n", magic[0],magic[1],magic[2],magic[3]);
break;
}
}
Zf (fclose(fp), "can't close: %s", sif_path);
return squash_offset;
}

/* Mount the SquashFS img_path at mountpt. Exit on any errors. */
void sq_mount(const char *img_path, char *mountpt)
{
Expand All @@ -231,7 +260,11 @@ void sq_mount(const char *img_path, char *mountpt)
sq.mountpt = mountpt;
T_ (sq.chan = malloc(sizeof(sqfs_ll_chan)));

sq.ll = sqfs_ll_open(img_path, 0);
int byte_offset = 0;

byte_offset = sq_offset(img_path);
sq.ll = sqfs_ll_open(img_path, byte_offset);

Te (sq.ll != NULL, "can't open SquashFS: %s; try ch-run -vv?", img_path);

// sqfs_ll_mount() is squirrely for a couple reasons:
Expand Down
1 change: 1 addition & 0 deletions bin/ch_fuse.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
/** Function prototypes **/

void sq_fork(struct container *c);
int sq_offset(const char *sif_path);