* GPL HEADER END
*/
/*
- * Copyright (c) 2012, 2014, Intel Corporation.
+ * Copyright (c) 2012, 2016, Intel Corporation.
* Use is subject to license terms.
*/
/*
#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"
{
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);
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) {
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) {
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++) {
{
nvlist_t *props;
nvpair_t *nvp;
- char key[ZFS_MAXNAMELEN];
+ char key[ZFS_MAXPROPLEN];
char *value;
int ret = 0;
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];
return EINVAL;
}
+ ret = zfs_check_hostid(mop);
+ if (ret != 0)
+ goto out;
+
pool = strdup(ds);
if (pool == NULL)
return ENOMEM;
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;
}