|
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 |
}
|