]> git.neil.brown.name Git - lafs-utils.git/commitdiff
Split open_device out of mkfs.lafs
authorNeilBrown <neilb@suse.de>
Sun, 13 Mar 2011 22:46:17 +0000 (09:46 +1100)
committerNeilBrown <neilb@suse.de>
Sun, 13 Mar 2011 22:46:17 +0000 (09:46 +1100)
'lafs' will need this, so make it a separate file.
Not in liblafs as it isn't really that generic.

Signed-off-by: NeilBrown <neilb@suse.de>
tools/Makefile
tools/internal.h [new file with mode: 0644]
tools/mkfs.lafs.c
tools/open_device.c [new file with mode: 0644]

index 98ebab9a0106168b149afb7a6e750c53e7be884c..fb9e830e1584af1f3730365e8a1ba54335368238 100644 (file)
 CPPFLAGS = -I../include
 CFLAGS = -Wall -Werror -g
 LDFLAGS = -L../lib
-LDLIBS = -llafs -ltalloc -lreadline -luuid
+LDLIBS = libinternal.a -llafs -ltalloc -lreadline -luuid
 
-all : mkfs.lafs lafs
+# 'internal' library
+LIBSRC = open_device.c
+LIBOBJ = $(patsubst %.c,%.o,$(LIBSRC))
 
-mkfs.lafs : mkfs.lafs.o ../lib/liblafs.a
+all : mkfs.lafs lafs libinternal.a
 
-lafs : lafs.o ../lib/liblafs.a
+mkfs.lafs : mkfs.lafs.o ../lib/liblafs.a libinternal.a
+
+lafs : lafs.o ../lib/liblafs.a libinternal.a
+
+libinternal.a : $(LIBOBJ) internal.h
+       ar cr libinternal.a $(LIBOBJ)
+       ranlib libinternal.a
diff --git a/tools/internal.h b/tools/internal.h
new file mode 100644 (file)
index 0000000..436fc73
--- /dev/null
@@ -0,0 +1,3 @@
+
+int open_device(char *devname, long long *device_bytes, int regular_file,
+               char **error);
index 5609321020f506afb7ec323388b245d43ba6a720..24cd15432593b719cef24596c9ad6d92f548c2e5 100644 (file)
 #include <stdlib.h>
 #include <stdio.h>
 #include <getopt.h>
-#include <sys/stat.h>
-#include <sys/ioctl.h>
-#include <sys/mount.h>
-#include <fcntl.h>
-#include <errno.h>
-#include <string.h>
 #include <lafs/lafs.h>
 #include <talloc.h>
 
+#include "internal.h"
+
 /*
  * A new filesystem must contain:
  *   inode 0 - TypeInodeFile with all the files listed here
@@ -165,51 +161,6 @@ void get_num(int *valp, char *arg, char *name)
        *valp = val;
 }
 
-int open_device(char *devname, long long *device_bytes, int regular_file)
-{
-       /* must be able to get an exclusive open on the device and its size
-        * must be non-trivial
-        * If 'regular_file', then expect a regular file to be used instead.
-        */
-       int fd;
-       struct stat stb;
-       unsigned long long size = 0;
-
-       fd = open(devname, O_RDWR|O_EXCL);
-       if (fd < 0 || fstat(fd, &stb) < 0) {
-               fprintf(stderr, "mkfs.lafs: cannot open device %s: %s\n",
-                       devname, strerror(errno));
-               exit(2);
-       }
-
-       if (regular_file) {
-               if ((stb.st_mode & S_IFMT) != S_IFREG)
-                       fprintf(stderr, "mkfs.lafs: %s is not a regular file\n",
-                               devname);
-               else
-                       size = stb.st_size;
-       } else {
-               if ((stb.st_mode & S_IFMT) != S_IFBLK)
-                       fprintf(stderr, "mkfs.lafs: %s is not a block device\n",
-                               devname);
-               else if (ioctl(fd, BLKGETSIZE64, &size) != 0)
-                       fprintf(stderr, "mkfs.lafs: Cannot get size of %s\n",
-                               devname);
-               else if (size == 0)
-                       size = 1;/*ensure we get an error */
-       }
-       if (size == 0)
-               ;
-       else if (size < 64*1024)
-               fprintf(stderr, "mkfs.lafs: %s is too small for a LAFS filesystem\n",
-                       devname);
-       else {
-               *device_bytes = size;
-               return fd;
-       }
-       exit(2);
-}
-
 int main(int argc, char *argv[])
 {
        int verbose = 0;
@@ -285,7 +236,12 @@ int main(int argc, char *argv[])
        }
 
        /* Validate device */
-       dev_fd = open_device(devname, &device_bytes, regular_file);
+       dev_fd = open_device(devname, &device_bytes, regular_file, &error);
+       if (dev_fd < 0) {
+               fprintf(stderr, "mkfs.lafs: %s\n", error);
+               free(error);
+               exit(2);
+       }
 
        /* Validate parameters */
        error = lafs_validate_geometry(&block_bytes, &segment_bytes,
diff --git a/tools/open_device.c b/tools/open_device.c
new file mode 100644 (file)
index 0000000..ba06941
--- /dev/null
@@ -0,0 +1,77 @@
+
+/* support routine to open device or file for lafs tools. */
+
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include "internal.h"
+
+int open_device(char *devname, long long *device_bytes, int regular_file,
+               char **error)
+{
+       /* must be able to get an exclusive open on the device and its size
+        * must be non-trivial
+        * If 'regular_file', then expect a regular file to be used instead.
+        * If device_bytes is already non-zero then it is OK to create
+        * a regular file.
+        */
+       int fd;
+       struct stat stb;
+       unsigned long long size = 0;
+
+       *error = NULL;
+
+       if (!regular_file)
+               fd = open(devname, O_RDWR|O_EXCL);
+       else if (*device_bytes)
+               fd = open(devname, O_RDWR|O_CREAT, 0666);
+       else
+               fd = open(devname, O_RDWR);
+       if (fd < 0 || fstat(fd, &stb) < 0) {
+               asprintf(error, "cannot open %s %s:%s",
+                        regular_file? "file" : "device",
+                        devname, strerror(errno));
+               return -1;
+       }
+
+       if (regular_file) {
+               if ((stb.st_mode & S_IFMT) != S_IFREG)
+                       asprintf(error, "%s is not a regular file",
+                               devname);
+               else {
+                       if (*device_bytes) {
+                               char zero = 0;
+                               lseek64(fd, *device_bytes-1, 0);
+                               write(fd, &zero, 1);
+                               fstat(fd, &stb);
+                       }
+                       size = stb.st_size;
+               }
+       } else {
+               if ((stb.st_mode & S_IFMT) != S_IFBLK)
+                       asprintf(error, "%s is not a block device",
+                               devname);
+               else if (ioctl(fd, BLKGETSIZE64, &size) != 0)
+                       asprintf(error, "Cannot get size of %s",
+                               devname);
+       }
+
+       if (!error && size < 64*1024)
+               asprintf(error, "%s is too small for a LAFS filesystem",
+                       devname);
+
+       if (*error) {
+               close(fd);
+               return -1;
+       }
+       *device_bytes = size;
+       lseek64(fd, 0, 0);
+       return fd;
+}