X-Git-Url: http://git.ipfire.org/?p=ipfire-2.x.git;a=blobdiff_plain;f=src%2Finstaller%2Fhw.c;fp=src%2Finstaller%2Fhw.c;h=651ffdf27c696a1560813388fcc74077baa007ad;hp=9b9a2d00291ae7b6911bd5eb10848e7c31c444a9;hb=c0511f3ab35cc059e0777b7481eaee105c738f5e;hpb=2404450b403607c9f08745b16b04eaf2bd1dac83 diff --git a/src/installer/hw.c b/src/installer/hw.c index 9b9a2d0029..651ffdf27c 100644 --- a/src/installer/hw.c +++ b/src/installer/hw.c @@ -26,12 +26,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -82,11 +84,56 @@ static int strstartswith(const char* a, const char* b) { return (strncmp(a, b, strlen(b)) == 0); } +static char loop_device[STRING_SIZE]; + +static int setup_loop_device(const char* source, const char* device) { + int file_fd = open(source, O_RDWR); + if (file_fd < 0) + goto ERROR; + + int device_fd = -1; + if ((device_fd = open(device, O_RDWR)) < 0) + goto ERROR; + + if (ioctl(device_fd, LOOP_SET_FD, file_fd) < 0) + goto ERROR; + + close(file_fd); + close(device_fd); + + return 0; + +ERROR: + if (file_fd >= 0) + close(file_fd); + + if (device_fd >= 0) { + ioctl(device_fd, LOOP_CLR_FD, 0); + close(device_fd); + } + + return -1; +} + int hw_mount(const char* source, const char* target, const char* fs, int flags) { + const char* loop_device = "/dev/loop0"; + // Create target if it does not exist if (access(target, X_OK) != 0) mkdir(target, S_IRWXU|S_IRWXG|S_IRWXO); + struct stat st; + stat(source, &st); + + if (S_ISREG(st.st_mode)) { + int r = setup_loop_device(source, loop_device); + if (r == 0) { + source = loop_device; + } else { + return -1; + } + } + return mount(source, target, fs, flags, NULL); }