#include <lnet/lnetctl.h>
#include <lustre_ver.h>
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
#define MAX_HW_SECTORS_KB_PATH "queue/max_hw_sectors_kb"
#define MAX_SECTORS_KB_PATH "queue/max_sectors_kb"
+#define SCHEDULER_PATH "queue/scheduler"
#define STRIPE_CACHE_SIZE "md/stripe_cache_size"
+#define DEFAULT_SCHEDULER "deadline"
+
extern char *progname;
#define L_BLOCK_SIZE 4096
#define DUMMY_FILE_NAME_LEN 25
#define EXT3_DIRENT_SIZE DUMMY_FILE_NAME_LEN
+/*
+ * Concatenate context of the temporary mount point iff selinux is enabled
+ */
+#ifdef HAVE_SELINUX
+void append_context_for_mount(char *mntpt, struct mkfs_opts *mop)
+{
+ security_context_t fcontext;
+
+ if (getfilecon(mntpt, &fcontext) < 0) {
+ /* Continuing with default behaviour */
+ fprintf(stderr, "%s: Get file context failed : %s\n",
+ progname, strerror(errno));
+ return;
+ }
+
+ if (fcontext != NULL) {
+ strcat(mop->mo_ldd.ldd_mount_opts, ",context=");
+ strcat(mop->mo_ldd.ldd_mount_opts, fcontext);
+ freecon(fcontext);
+ }
+}
+#endif
+
/* Write the server config files */
int ldiskfs_write_ldd(struct mkfs_opts *mop)
{
return errno;
}
+ /*
+ * Append file context to mount options if SE Linux is enabled
+ */
+ #ifdef HAVE_SELINUX
+ if (is_selinux_enabled() > 0)
+ append_context_for_mount(mntpt, mop);
+ #endif
+
dev = mop->mo_device;
if (mop->mo_flags & MO_IS_LOOP)
dev = mop->mo_loopdev;
return 0;
}
-int read_file(char *path, char *buf, int size)
+int read_file(const char *path, char *buf, int size)
{
FILE *fd;
return 0;
}
-int write_file(char *path, char *buf)
+int write_file(const char *path, const char *buf)
{
FILE *fd;
return 0;
}
+int set_blockdev_scheduler(const char *path, const char *scheduler)
+{
+ char buf[PATH_MAX], *c;
+ int rc;
+
+ /* Before setting the scheduler, we need to check to see if it's
+ * already set to "noop". If it is, we don't want to override
+ * that setting. If it's set to anything other than "noop", set
+ * the scheduler to what has been passed in. */
+
+ rc = read_file(path, buf, sizeof(buf));
+ if (rc) {
+ if (verbose)
+ fprintf(stderr, "%s: cannot open '%s': %s\n",
+ progname, path, strerror(errno));
+ return rc;
+ }
+
+ /* The expected format of buf: noop anticipatory deadline [cfq] */
+ c = strchr(buf, '[');
+
+ /* If c is NULL, the format is not what we expect. Play it safe
+ * and error out. */
+ if (c == NULL) {
+ if (verbose)
+ fprintf(stderr, "%s: cannot parse scheduler "
+ "options for '%s'\n", progname, path);
+ return -EINVAL;
+ }
+
+ if (strncmp(c+1, "noop", 4) == 0)
+ return 0;
+
+ rc = write_file(path, scheduler);
+ if (rc) {
+ if (verbose)
+ fprintf(stderr, "%s: cannot set scheduler on "
+ "'%s': %s\n", progname, path,
+ strerror(errno));
+ return rc;
+ }
+
+ return rc;
+}
+
/* This is to tune the kernel for good SCSI performance.
* For that we set the value of /sys/block/{dev}/queue/max_sectors_kb
* to the value of /sys/block/{dev}/queue/max_hw_sectors_kb */
}
}
+ /* Purposely ignore errors reported from set_blockdev_scheduler.
+ * The worst that will happen is a block device with an "incorrect"
+ * scheduler. */
+ snprintf(real_path, sizeof(real_path), "%s/%s", path, SCHEDULER_PATH);
+ set_blockdev_scheduler(real_path, DEFAULT_SCHEDULER);
+
if (fan_out) {
char *slave = NULL;
glob_info.gl_pathc = 0;