/* * lsbd-setup.c * Copyright (C) 2010 Krzysztof Mazur * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Fundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include #include #include #include #include #include #include #include #include #include #ifndef major #define major(x) ((x) >> 8) #define minor(x) ((x) & 0xff) #endif static char *device = NULL; static char *ldevice = NULL; static int partition = -1; static unsigned int start = 0; static unsigned int size = 0; static int mirror = 0; static void show_info(void) { fprintf(stderr, "lsbd-setup "PACKAGE_VERSION"\n" "Copyright (C) 2010 " "Krzysztof Mazur \n\n"); } static void show_usage(char *name) { show_info(); fprintf(stderr, "usage: %s [options] (file)\n" "Options:\n" " -b, --start set partition start\n" " -h, --help show this help\n" " -p, --partition partition number\n" " -s, --size set partition size\n" " -m, --mirror use mirroring\n" " -V, --version show version\n", (name == NULL) ? "lsbd-setup" : name); exit(0); } static void parse_command_line(int argc, char **args) { int c; int option_index = 0; static struct option long_options[] = { {"help", 0, 0, 'h'}, {"mirror", 0, 0, 'm'}, {"partition", 1, 0, 'p'}, {"size", 1, 0, 's'}, {"start", 1, 0, 'b'}, {"version", 0, 0, 'V'}, {0, 0, 0, 0}, }; while (1) { c = getopt_long(argc, args, "b:hmp:s:V", long_options, &option_index); if (c == -1) break; switch (c) { case 'b': start = atoi(optarg); break; case 'h': show_usage(args[0]); break; case 'm': mirror = 1; break; case 'p': partition = atoi(optarg); break; case 's': size = atoi(optarg); break; case 'V': exit(0); break; default: fprintf(stderr, "Unknown option.\n"); exit(1); } } if (optind < argc) { device = args[optind++]; if (optind < argc) ldevice = args[optind++]; } } int main(int argc, char **argv) { int ret; int fd; struct stat s; int nr_major; int nr_minor; unsigned long arg; parse_command_line(argc, argv); if (device == NULL) { fprintf(stderr, "error: device option is required\n"); exit(EXIT_FAILURE); } if (partition < 0) { if (ldevice == NULL) { fprintf(stderr, "error: ldevice option is required\n"); exit(EXIT_FAILURE); } } fd = open(device, O_RDWR); if (fd == -1) { perror("open"); exit(EXIT_FAILURE); } if (partition >= 0) { struct lsbd_part_info info; info.num = partition; info.start = start; info.size = size; info.flags = 0; if (mirror) info.flags = 1; ret = ioctl(fd, LSBD_PART, &info); if (ret) { perror("ioctl"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); } ret = stat(ldevice, &s); if (ret == -1) { perror("stat"); exit(EXIT_FAILURE); } if (!S_ISBLK(s.st_mode)) { fprintf(stderr, "error: %s is not a block device\n", ldevice); exit(EXIT_FAILURE); } nr_major = major(s.st_rdev); nr_minor = minor(s.st_rdev); arg = (nr_major << 20) | nr_minor; ret = ioctl(fd, LSBD_SET_DEV, arg); if (ret) { perror("ioctl"); exit(EXIT_FAILURE); } exit(EXIT_SUCCESS); }