Blame gfs2/mkfs/metafs.c

Packit Service 360c39
#include <stdlib.h>
Packit Service 360c39
#include <string.h>
Packit Service 360c39
#include <stdio.h>
Packit Service 360c39
#include <unistd.h>
Packit Service 360c39
#include <sys/file.h>
Packit Service 360c39
#include <sys/types.h>
Packit Service 360c39
#include <sys/stat.h>
Packit Service 360c39
#include <sys/mount.h>
Packit Service 360c39
#include <fcntl.h>
Packit Service 360c39
#include <errno.h>
Packit Service 360c39
#include <signal.h>
Packit Service 360c39
#include <mntent.h>
Packit Service 360c39
#include <libintl.h>
Packit Service 360c39
#include <locale.h>
Packit Service 360c39
#define _(String) gettext(String)
Packit Service 360c39
Packit Service 360c39
#include "metafs.h"
Packit Service 360c39
Packit Service 360c39
int metafs_interrupted;
Packit Service 360c39
Packit Service 360c39
static int lock_for_admin(struct metafs *mfs, int debug)
Packit Service 360c39
{
Packit Service 360c39
	int error;
Packit Service 360c39
Packit Service 360c39
	if (debug)
Packit Service 360c39
		printf(_("Trying to get admin lock..."));
Packit Service 360c39
Packit Service 360c39
	mfs->fd = open(mfs->path, O_RDONLY | O_NOFOLLOW);
Packit Service 360c39
	if (mfs->fd < 0)
Packit Service 360c39
		return -1;
Packit Service 360c39
Packit Service 360c39
	error = flock(mfs->fd, LOCK_EX);
Packit Service 360c39
	if (error) {
Packit Service 360c39
		close(mfs->fd);
Packit Service 360c39
		return -1;
Packit Service 360c39
	}
Packit Service 360c39
	if (debug)
Packit Service 360c39
		printf(_("locked.\n"));
Packit Service 360c39
	return 0;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void sighandler(int error)
Packit Service 360c39
{
Packit Service 360c39
	metafs_interrupted = 1;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
static void setsigs(void (*handler)(int))
Packit Service 360c39
{
Packit Service 360c39
	struct sigaction sa = {	.sa_handler = handler };
Packit Service 360c39
Packit Service 360c39
	sigaction(SIGINT, &sa, NULL);
Packit Service 360c39
	sigaction(SIGILL, &sa, NULL);
Packit Service 360c39
	sigaction(SIGTERM, &sa, NULL);
Packit Service 360c39
	sigaction(SIGHUP, &sa, NULL);
Packit Service 360c39
	sigaction(SIGABRT, &sa, NULL);
Packit Service 360c39
	sigaction(SIGCONT, &sa, NULL);
Packit Service 360c39
	sigaction(SIGUSR1, &sa, NULL);
Packit Service 360c39
	sigaction(SIGUSR2, &sa, NULL);
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
int mount_gfs2_meta(struct metafs *mfs, const char *path, int debug)
Packit Service 360c39
{
Packit Service 360c39
	int ret;
Packit Service 360c39
Packit Service 360c39
	mfs->path = strdup("/tmp/.gfs2meta.XXXXXX");
Packit Service 360c39
	if (mfs->path == NULL)
Packit Service 360c39
		return -1;
Packit Service 360c39
Packit Service 360c39
	if(!mkdtemp(mfs->path))
Packit Service 360c39
		goto err_free;
Packit Service 360c39
Packit Service 360c39
	setsigs(sighandler);
Packit Service 360c39
Packit Service 360c39
	ret = mount(path, mfs->path, "gfs2meta", 0, mfs->context);
Packit Service 360c39
	if (ret)
Packit Service 360c39
		goto err_rmdir;
Packit Service 360c39
Packit Service 360c39
	if (lock_for_admin(mfs, debug))
Packit Service 360c39
		goto err_umount;
Packit Service 360c39
Packit Service 360c39
	return 0;
Packit Service 360c39
Packit Service 360c39
err_umount:
Packit Service 360c39
	if (umount(mfs->path))
Packit Service 360c39
		/* Translators: the first %s here is a path, the second is an error message */
Packit Service 360c39
		fprintf(stderr, _("Could not unmount %s: %s\n"),
Packit Service 360c39
		                    mfs->path, strerror(errno));
Packit Service 360c39
	setsigs(SIG_DFL);
Packit Service 360c39
err_rmdir:
Packit Service 360c39
	rmdir(mfs->path);
Packit Service 360c39
err_free:
Packit Service 360c39
	free(mfs->path);
Packit Service 360c39
	mfs->path = NULL;
Packit Service 360c39
	return -1;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
void cleanup_metafs(struct metafs *mfs)
Packit Service 360c39
{
Packit Service 360c39
	int ret;
Packit Service 360c39
Packit Service 360c39
	if (mfs->fd <= 0)
Packit Service 360c39
		return;
Packit Service 360c39
Packit Service 360c39
	fsync(mfs->fd);
Packit Service 360c39
	close(mfs->fd);
Packit Service 360c39
	ret = umount(mfs->path);
Packit Service 360c39
	if (ret)
Packit Service 360c39
		/* Translators: the first %s here is a path, the second is an error message */
Packit Service 360c39
		fprintf(stderr, "Could not unmount %s : %s\n",
Packit Service 360c39
			mfs->path, strerror(errno));
Packit Service 360c39
	else
Packit Service 360c39
		rmdir(mfs->path);
Packit Service 360c39
Packit Service 360c39
	setsigs(SIG_DFL);
Packit Service 360c39
	metafs_interrupted = 0;
Packit Service 360c39
Packit Service 360c39
	free(mfs->path);
Packit Service 360c39
	mfs->path = NULL;
Packit Service 360c39
	free(mfs->context);
Packit Service 360c39
	mfs->context = NULL;
Packit Service 360c39
}
Packit Service 360c39
Packit Service 360c39
/**
Packit Service 360c39
 * Returns a duplicate of the 'context' mount option, or NULL if not found.
Packit Service 360c39
 */
Packit Service 360c39
char *copy_context_opt(struct mntent *mnt)
Packit Service 360c39
{
Packit Service 360c39
	char *ctx, *end;
Packit Service 360c39
Packit Service 360c39
	ctx = hasmntopt(mnt, "context");
Packit Service 360c39
	if (ctx == NULL)
Packit Service 360c39
		return NULL;
Packit Service 360c39
Packit Service 360c39
	end = strchr(ctx, ',');
Packit Service 360c39
	if (end == NULL)
Packit Service 360c39
		return NULL;
Packit Service 360c39
Packit Service 360c39
	return strndup(ctx, end - ctx);
Packit Service 360c39
}