]> git.proxmox.com Git - mirror_zfs.git/blobdiff - cmd/zvol_id/zvol_id_main.c
Replace config/config.awk with simple sed invocation
[mirror_zfs.git] / cmd / zvol_id / zvol_id_main.c
index d9c80b3f90f7549b9d605347a1d57a1f2c492d90..929a1a6e794d2c6e978e376f52c075c0b65356d4 100644 (file)
@@ -23,6 +23,8 @@
  * Use is subject to license terms.
  */
 
+#include <ctype.h>
+#include <string.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <fcntl.h>
 #include <sys/zfs_znode.h>
 #include <sys/fs/zfs.h>
 
+#if defined(ZFS_ASAN_ENABLED)
+/*
+ * zvol_id is invoked by udev with the help of ptrace()
+ * making sanitized binary with leak detection croak
+ * because of tracing mechanisms collision
+ */
+extern const char *__asan_default_options(void);
+
+const char *__asan_default_options(void) {
+       return ("abort_on_error=true:halt_on_error=true:"
+               "allocator_may_return_null=true:disable_coredump=false:"
+               "detect_stack_use_after_return=true:detect_leaks=false");
+}
+#endif
+
 static int
 ioctl_get_msg(char *var, int fd)
 {
-       int error = 0;
-       char msg[ZFS_MAXNAMELEN];
+       int ret;
+       char msg[ZFS_MAX_DATASET_NAME_LEN];
 
-       error = ioctl(fd, BLKZNAME, msg);
-       if (error < 0) {
-               return (error);
+       ret = ioctl(fd, BLKZNAME, msg);
+       if (ret < 0) {
+               return (ret);
        }
 
-       snprintf(var, ZFS_MAXNAMELEN, "%s", msg);
-       return (error);
+       snprintf(var, ZFS_MAX_DATASET_NAME_LEN, "%s", msg);
+       return (ret);
 }
 
 int
 main(int argc, char **argv)
 {
-       int fd, error = 0;
-       char zvol_name[ZFS_MAXNAMELEN], zvol_name_part[ZFS_MAXNAMELEN];
+       int fd = -1, ret = 0, status = EXIT_FAILURE;
+       char zvol_name[ZFS_MAX_DATASET_NAME_LEN];
+       char *zvol_name_part = NULL;
        char *dev_name;
        struct stat64 statbuf;
        int dev_minor, dev_part;
+       int i;
 
        if (argc < 2) {
-               printf("Usage: %s /dev/zvol_device_node\n", argv[0]);
-               return (EINVAL);
+               fprintf(stderr, "Usage: %s /dev/zvol_device_node\n", argv[0]);
+               goto fail;
        }
 
        dev_name = argv[1];
-       error = stat64(dev_name, &statbuf);
-       if (error != 0) {
-               printf("Unable to access device file: %s\n", dev_name);
-               return (errno);
+       ret = stat64(dev_name, &statbuf);
+       if (ret != 0) {
+               fprintf(stderr, "Unable to access device file: %s\n", dev_name);
+               goto fail;
        }
 
        dev_minor = minor(statbuf.st_rdev);
@@ -74,22 +93,37 @@ main(int argc, char **argv)
 
        fd = open(dev_name, O_RDONLY);
        if (fd < 0) {
-               printf("Unable to open device file: %s\n", dev_name);
-               return (errno);
+               fprintf(stderr, "Unable to open device file: %s\n", dev_name);
+               goto fail;
        }
 
-       error = ioctl_get_msg(zvol_name, fd);
-       if (error < 0) {
-               printf("ioctl_get_msg failed:%s\n", strerror(errno));
-               return (errno);
+       ret = ioctl_get_msg(zvol_name, fd);
+       if (ret < 0) {
+               fprintf(stderr, "ioctl_get_msg failed: %s\n", strerror(errno));
+               goto fail;
        }
        if (dev_part > 0)
-               snprintf(zvol_name_part, ZFS_MAXNAMELEN, "%s-part%d", zvol_name,
+               ret = asprintf(&zvol_name_part, "%s-part%d", zvol_name,
                    dev_part);
        else
-               snprintf(zvol_name_part, ZFS_MAXNAMELEN, "%s", zvol_name);
+               ret = asprintf(&zvol_name_part, "%s", zvol_name);
+
+       if (ret == -1 || zvol_name_part == NULL)
+               goto fail;
+
+       for (i = 0; i < strlen(zvol_name_part); i++) {
+               if (isblank(zvol_name_part[i]))
+                       zvol_name_part[i] = '+';
+       }
 
        printf("%s\n", zvol_name_part);
-       close(fd);
-       return (error);
+       status = EXIT_SUCCESS;
+
+fail:
+       if (zvol_name_part)
+               free(zvol_name_part);
+       if (fd >= 0)
+               close(fd);
+
+       return (status);
 }