Instantly share code, notes, and snippets.
Created
April 22, 2020 12:24
-
Save brauner/dcaf15e6977cc1bfadfb3965f126c02f to your computer and use it in GitHub Desktop.
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
#ifndef _GNU_SOURCE | |
#define _GNU_SOURCE 1 | |
#endif | |
#include <linux/loop.h> | |
#include <dirent.h> | |
#include <errno.h> | |
#include <fcntl.h> | |
#include <inttypes.h> | |
#include <limits.h> | |
#include <linux/bpf.h> | |
#include <linux/magic.h> | |
#include <linux/sched.h> | |
#include <malloc.h> | |
#include <poll.h> | |
#include <pthread.h> | |
#include <sched.h> | |
#include <signal.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include <sys/fsuid.h> | |
#include <sys/mman.h> | |
#include <sys/mount.h> | |
#include <sys/param.h> | |
#include <sys/socket.h> | |
#include <sys/stat.h> | |
#include <sys/types.h> | |
#include <linux/types.h> | |
#include <sys/un.h> | |
#include <sys/wait.h> | |
#include <unistd.h> | |
int attach_image_to_loop(const char *source, int loop_fd) | |
{ | |
int ret, fret = -1; | |
struct loop_info64 lo64; | |
int fd_img = -1; | |
fd_img = open(source, O_RDWR | O_CLOEXEC); | |
if (fd_img < 0) { | |
fprintf(stderr, "Failed to open %s\n", source); | |
goto on_error; | |
} | |
ret = ioctl(loop_fd, LOOP_SET_FD, fd_img); | |
if (ret < 0) { | |
fprintf(stderr, "%m - Failed to set loop device to %s\n", source); | |
goto on_error; | |
} | |
memset(&lo64, 0, sizeof(lo64)); | |
snprintf((char *)lo64.lo_file_name, LO_NAME_SIZE, "%s", source); | |
ret = ioctl(loop_fd, LOOP_SET_STATUS64, &lo64); | |
if (ret < 0) { | |
fprintf(stderr, "%m - Failed to set loop device status for %s\n", source); | |
goto on_error; | |
} | |
fret = 0; | |
on_error: | |
if (fd_img >= 0) | |
close(fd_img); | |
return fret; | |
} | |
int main(int argc, char *argv[]) | |
{ | |
int ret, mntfd, loop_ctl_fd, loopidx, loop_fd; | |
char *image, *mntpt, *target, *fstype; | |
char path[4096]; | |
int n = 1; | |
if (argc < 5) | |
exit(EXIT_FAILURE); | |
mntpt = argv[1]; | |
image = argv[2]; | |
target = argv[3]; | |
fstype = argv[4]; | |
ret = mount("none", mntpt, "loop", 0, 0); | |
if (ret) { | |
fprintf(stderr, "%m - Failed to mount loopfs at %s\n", mntpt); | |
exit(EXIT_FAILURE); | |
} | |
mntfd = open(mntpt, O_DIRECTORY | O_CLOEXEC); | |
if (mntfd < 0) { | |
fprintf(stderr, "%m - Failed to open loopfs mount %s\n", mntpt); | |
exit(EXIT_FAILURE); | |
} | |
(void)snprintf(path, sizeof(path), "%s/loop-control", mntpt); | |
loop_ctl_fd = open(path, O_RDWR | O_CLOEXEC); | |
if (loop_ctl_fd < 0) { | |
fprintf(stderr, | |
"%m - Failed to open loopfs loop-control device %s\n", | |
path); | |
exit(EXIT_FAILURE); | |
} | |
ret = umount2(mntpt, MNT_DETACH); | |
if (ret) { | |
fprintf(stderr, "%m - Failed to unmount loopfs at %s\n", mntpt); | |
exit(EXIT_FAILURE); | |
} | |
loopidx = ioctl(loop_ctl_fd, LOOP_CTL_GET_FREE); | |
if (loopidx < 0) { | |
fprintf(stderr, "%m - Failed to get new loopfs loop device\n"); | |
exit(EXIT_FAILURE); | |
} | |
(void)snprintf(path, sizeof(path), "loop%d", loopidx); | |
loop_fd = openat(mntfd, path, O_RDWR | O_CLOEXEC); | |
if (loop_fd < 0) { | |
fprintf(stderr, "%m - Failed to open loop device %s\n", path); | |
exit(EXIT_FAILURE); | |
} | |
printf("Opened loop device %s\n", path); | |
ret = attach_image_to_loop(image, loop_fd); | |
if (ret) { | |
fprintf(stderr, | |
"%m - Failed to attach image %s to loop device %s\n", | |
image, path); | |
exit(EXIT_FAILURE); | |
} | |
printf("Attached image %s to loop device %s\n", image, path); | |
snprintf(path, sizeof(path), "/proc/self/fd/%d", loop_fd); | |
ret = mount(path, tardetachedget, fstype, 0, 0); | |
if (ret) { | |
fprintf(stderr, "%m - Failed to mount %s to %s\n", path, target); | |
exit(EXIT_FAILURE); | |
} | |
printf("Mounted %s to %s\n", path, target); | |
exit(EXIT_SUCCESS); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment