} // End Function Unmount public static string find_unused_loop_device() { string dev; int fd; Mono.Unix.Native.Stat statbuf; loop_info loopinfo = new loop_info(); loop_info64 lo64 = new loop_info64(); for (int i = 0; i <= 7; i++) { dev = "/dev/loop" + i.ToString(); if (System.Convert.ToBoolean(Mono.Unix.Native.Syscall.stat(dev, out statbuf)) == (false && S_ISBLK((int)statbuf.st_mode))) { if ((fd = Mono.Unix.Native.Syscall.open(dev, Mono.Unix.Native.OpenFlags.O_RDONLY)) >= 0) { // This block was commented out initially if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS64, ref lo64) == 0) { if (Mono.Unix.Native.Syscall.GetLastError() == Mono.Unix.Native.Errno.ENXIO) { // probably free Mono.Unix.Native.Syscall.close(fd); return(dev); } } if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS, ref loopinfo) != 0) { // http://tomoyo.sourceforge.jp/cgi-bin/lxr/source/include/asm-generic/errno-base.h#L9 // ENXIO - No such device or address // The device accessed by a command is physically not present, // or the address of the device is not present if (Mono.Unix.Native.Syscall.GetLastError() == Mono.Unix.Native.Errno.ENXIO) { // that means the device is most-likely free Mono.Unix.Native.Syscall.close(fd); return(dev); } } // End if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS, ref loopinfo) != 0) Mono.Unix.Native.Syscall.close(fd); } // End if ((fd = UnsafeNativeMethods.open(dev, OpenFlags.O_RDONLY)) >= 0) } // End if (System.Convert.ToBoolean(Mono.Unix.Native.Syscall.stat(dev, out statbuf)) == (false && S_ISBLK((int)statbuf.st_mode))) } // Next i return(null); } // End Function find_unused_loop_device
} // End Function loopfile_from_sysfs public static string loopdev_get_loopfile(string device) { string res = loopfile_from_sysfs(device); if (res == null) { loop_info lo = new loop_info(); loop_info64 lo64 = new loop_info64(); int fd; if ((fd = Mono.Unix.Native.Syscall.open(device, Mono.Unix.Native.OpenFlags.O_RDONLY)) < 0) { return(null); } if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS64, ref lo64) == 0) { //lo64.lo_file_name[LO_NAME_SIZE-2] = '*'; //lo64.lo_file_name[LO_NAME_SIZE-1] = 0; //res = strdup((char *) lo64.lo_file_name); res = lo64.lo_file_name; Console.WriteLine("LOOP_GET_STATUS64"); } else if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS, ref lo) == 0) { //lo.lo_name[LO_NAME_SIZE-2] = '*'; //lo.lo_name[LO_NAME_SIZE-1] = 0; //res = strdup((char *) lo.lo_name); res = lo.lo_name; Console.WriteLine("LOOP_GET_STATUS"); } Mono.Unix.Native.Syscall.close(fd); } // End if (res == null) return(res); } // End Function loopdev_get_loopfile
} // End Function loopfile_from_sysfs private static string loopdev_get_loopfile(string device) { string res = loopfile_from_sysfs(device); if (res == null) { loop_info lo = new loop_info(); loop_info64 lo64 = new loop_info64(); int fd; if ((fd = Mono.Unix.Native.Syscall.open(device, Mono.Unix.Native.OpenFlags.O_RDONLY)) < 0) { return(null); } if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS64, ref lo64) == 0) { //lo64.lo_file_name[LO_NAME_SIZE-2] = '*'; //lo64.lo_file_name[LO_NAME_SIZE-1] = 0; //res = strdup((char *) lo64.lo_file_name); res = lo64.lo_file_name; } else if (UnsafeNativeMethods.ioctl(fd, LOOP_GET_STATUS, ref lo) == 0) { //lo.lo_name[LO_NAME_SIZE-2] = '*'; //lo.lo_name[LO_NAME_SIZE-1] = 0; //res = strdup((char *) lo.lo_name); res = lo.lo_name; Logger.Append(P2PBackup.Common.Severity.TRIVIA, "Could not use LOOP_GET_STATUS64, defaulted to LOOP_GET_STATUS"); } Mono.Unix.Native.Syscall.close(fd); } // End if (res == null) return(res); } // End Function loopdev_get_loopfile
public static extern int ioctl(int d, int request, ref loop_info64 data);