Whamcloud - gitweb
LU-8735 llite: Return -ERESTARTSYS in range_lock()
[fs/lustre-release.git] / lustre / utils / mount_utils_zfs.c
index b1ca83d..72dbb69 100644 (file)
@@ -20,7 +20,7 @@
  * GPL HEADER END
  */
 /*
- * Copyright (c) 2012, 2014, Intel Corporation.
+ * Copyright (c) 2012, 2016, Intel Corporation.
  * Use is subject to license terms.
  */
 /*
@@ -32,6 +32,8 @@
 #include <string.h>
 #include <libzfs.h>
 
+#define HOSTID_PATH "/etc/hostid"
+
 /* Persistent mount data is stored in these user attributes */
 #define LDD_PREFIX             "lustre:"
 #define LDD_VERSION_PROP       LDD_PREFIX "version"
@@ -142,7 +144,7 @@ static int zfs_set_prop_params(zfs_handle_t *zhp, char *params)
 {
        char *params_dup, *token, *key, *value;
        char *save_token = NULL;
-       char prop_name[ZFS_MAXNAMELEN];
+       char prop_name[ZFS_MAXPROPLEN];
        int ret = 0;
 
        params_dup = strdup(params);
@@ -174,6 +176,62 @@ static int zfs_set_prop_params(zfs_handle_t *zhp, char *params)
        return ret;
 }
 
+static int zfs_check_hostid(struct mkfs_opts *mop)
+{
+       FILE *f;
+       unsigned long hostid;
+       int rc;
+
+       if (strstr(mop->mo_ldd.ldd_params, PARAM_FAILNODE) == NULL)
+               return 0;
+
+       f = fopen("/sys/module/spl/parameters/spl_hostid", "r");
+       if (f == NULL) {
+               fatal();
+               fprintf(stderr, "Failed to open spl_hostid: %s\n",
+                       strerror(errno));
+               return errno;
+       }
+       rc = fscanf(f, "%li", &hostid);
+       fclose(f);
+       if (rc != 1) {
+               fatal();
+               fprintf(stderr, "Failed to read spl_hostid: %d\n", rc);
+               return rc;
+       }
+
+       if (hostid != 0)
+               return 0;
+
+       f = fopen(HOSTID_PATH, "r");
+       if (f == NULL)
+               goto out;
+
+       rc = fread(&hostid, sizeof(uint32_t), 1, f);
+       fclose(f);
+
+       if (rc != 1) {
+               fprintf(stderr, "Failed to read "HOSTID_PATH": %d\n",
+                      rc);
+               hostid = 0;
+       }
+
+out:
+       if (hostid == 0) {
+               if (mop->mo_flags & MO_NOHOSTID_CHECK) {
+                       fprintf(stderr, "WARNING: spl_hostid not set. ZFS has "
+                               "no zpool import protection\n");
+               } else {
+                       fatal();
+                       fprintf(stderr, "spl_hostid not set. See %s(8)",
+                               progname);
+                       return EINVAL;
+               }
+       }
+
+       return 0;
+}
+
 static int osd_check_zfs_setup(void)
 {
        if (osd_zfs_setup == 0) {
@@ -195,7 +253,7 @@ int zfs_write_ldd(struct mkfs_opts *mop)
        int i, ret = EINVAL;
 
        if (osd_check_zfs_setup() == 0)
-               return EINVAL;
+               goto out;
 
        zhp = zfs_open(g_zfs, ds, ZFS_TYPE_FILESYSTEM);
        if (zhp == NULL) {
@@ -203,6 +261,10 @@ int zfs_write_ldd(struct mkfs_opts *mop)
                goto out;
        }
 
+       ret = zfs_check_hostid(mop);
+       if (ret != 0)
+               goto out;
+
        vprint("Writing %s properties\n", ds);
 
        for (i = 0; special_ldd_prop_params[i].zlpb_prop_name != NULL; i++) {
@@ -277,7 +339,7 @@ static int zfs_get_prop_params(zfs_handle_t *zhp, char *param, int len)
 {
        nvlist_t *props;
        nvpair_t *nvp;
-       char key[ZFS_MAXNAMELEN];
+       char key[ZFS_MAXPROPLEN];
        char *value;
        int ret = 0;
 
@@ -327,8 +389,11 @@ int zfs_read_ldd(char *ds,  struct lustre_disk_data *ldd)
                return EINVAL;
 
        zhp = zfs_open(g_zfs, ds, ZFS_TYPE_FILESYSTEM);
-       if (zhp == NULL)
-               goto out;
+       if (!zhp) {
+               zhp = zfs_open(g_zfs, ds, ZFS_TYPE_SNAPSHOT);
+               if (!zhp)
+                       goto out;
+       }
 
        for (i = 0; special_ldd_prop_params[i].zlpb_prop_name != NULL; i++) {
                bridge = &special_ldd_prop_params[i];
@@ -451,6 +516,10 @@ int zfs_make_lustre(struct mkfs_opts *mop)
                return EINVAL;
        }
 
+       ret = zfs_check_hostid(mop);
+       if (ret != 0)
+               goto out;
+
        pool = strdup(ds);
        if (pool == NULL)
                return ENOMEM;
@@ -611,18 +680,93 @@ int zfs_label_lustre(struct mount_opts *mop)
        return ret;
 }
 
+int zfs_rename_fsname(struct mkfs_opts *mop, const char *oldname)
+{
+       struct mount_opts opts;
+       char mntpt[] = "/tmp/mntXXXXXX";
+       char *cmd_buf;
+       int ret;
+
+       /* Change the filesystem label. */
+       opts.mo_ldd = mop->mo_ldd;
+       opts.mo_source = mop->mo_device;
+       ret = zfs_label_lustre(&opts);
+       if (ret) {
+               if (errno != 0)
+                       ret = errno;
+               fprintf(stderr, "Can't change filesystem label: %s\n",
+                       strerror(ret));
+               return ret;
+       }
+
+       /* Mount this device temporarily in order to write these files */
+       if (mkdtemp(mntpt) == NULL) {
+               if (errno != 0)
+                       ret = errno;
+               fprintf(stderr, "Can't create temp mount point %s: %s\n",
+                       mntpt, strerror(ret));
+               return ret;
+       }
+
+       cmd_buf = malloc(PATH_MAX);
+       if (!cmd_buf) {
+               ret = ENOMEM;
+               goto out_rmdir;
+       }
+
+       memset(cmd_buf, 0, PATH_MAX);
+       snprintf(cmd_buf, PATH_MAX - 1, "zfs set mountpoint=%s %s && "
+                "zfs set canmount=on %s && zfs mount %s",
+                mntpt, mop->mo_device, mop->mo_device, mop->mo_device);
+       ret = run_command(cmd_buf, PATH_MAX);
+       if (ret) {
+               if (errno != 0)
+                       ret = errno;
+               fprintf(stderr, "Unable to mount %s (%s)\n",
+                       mop->mo_device, strerror(ret));
+               if (ret == ENODEV)
+                       fprintf(stderr, "Is the %s module available?\n",
+                               MT_STR(&mop->mo_ldd));
+               goto out_free;
+       }
+
+       ret = lustre_rename_fsname(mop, mntpt, oldname);
+       memset(cmd_buf, 0, PATH_MAX);
+       snprintf(cmd_buf, PATH_MAX - 1, "zfs umount %s && "
+                "zfs set canmount=off %s && zfs set mountpoint=none %s",
+                mop->mo_device, mop->mo_device, mop->mo_device);
+       run_command(cmd_buf, PATH_MAX);
+
+out_free:
+       free(cmd_buf);
+out_rmdir:
+       rmdir(mntpt);
+       return ret;
+}
+
 int zfs_init(void)
 {
        int ret = 0;
 
        g_zfs = libzfs_init();
        if (g_zfs == NULL) {
-               fprintf(stderr, "Failed to initialize ZFS library\n");
-               ret = EINVAL;
-       } else {
-               osd_zfs_setup = 1;
+               /* Try to load zfs.ko and retry libzfs_init() */
+
+               ret = system("/sbin/modprobe -q zfs");
+
+               if (ret == 0) {
+                       g_zfs = libzfs_init();
+                       if (g_zfs == NULL)
+                               ret = EINVAL;
+               }
        }
 
+       if (ret == 0)
+               osd_zfs_setup = 1;
+
+       else
+               fprintf(stderr, "Failed to initialize ZFS library: %d\n", ret);
+
        return ret;
 }