|
Packit |
6ef888 |
#include <stdio.h>
|
|
Packit |
6ef888 |
#include <stdlib.h>
|
|
Packit |
6ef888 |
#include <sysexits.h>
|
|
Packit |
6ef888 |
#include <sys/types.h>
|
|
Packit |
6ef888 |
#include <sys/stat.h>
|
|
Packit |
6ef888 |
#include <errno.h>
|
|
Packit |
6ef888 |
#include <fcntl.h>
|
|
Packit |
6ef888 |
#include <unistd.h>
|
|
Packit |
6ef888 |
#include <ctype.h>
|
|
Packit |
6ef888 |
#include <string.h>
|
|
Packit |
6ef888 |
#include <libintl.h>
|
|
Packit |
6ef888 |
#define _(String) gettext(String)
|
|
Packit |
6ef888 |
#include <linux_endian.h>
|
|
Packit |
6ef888 |
#include <linux/gfs2_ondisk.h>
|
|
Packit |
6ef888 |
#include "tunegfs2.h"
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
#ifdef GFS2_HAS_UUID
|
|
Packit |
6ef888 |
#include <uuid.h>
|
|
Packit |
6ef888 |
#endif
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int read_super(struct tunegfs2 *tfs)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
void *block;
|
|
Packit |
6ef888 |
int n;
|
|
Packit |
6ef888 |
tfs->sb_start = GFS2_SB_ADDR << GFS2_BASIC_BLOCK_SHIFT;
|
|
Packit |
6ef888 |
block = malloc(sizeof(char) * GFS2_DEFAULT_BSIZE);
|
|
Packit |
6ef888 |
if (!block) {
|
|
Packit |
6ef888 |
perror("read_super: malloc");
|
|
Packit |
6ef888 |
return EX_UNAVAILABLE;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
n = pread(tfs->fd, block, GFS2_DEFAULT_BSIZE, tfs->sb_start);
|
|
Packit |
6ef888 |
if (n < 0) {
|
|
Packit |
6ef888 |
perror("read_super: pread");
|
|
Packit |
6ef888 |
free(block);
|
|
Packit |
6ef888 |
return EX_IOERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
tfs->sb = block;
|
|
Packit |
6ef888 |
if (be32_to_cpu(tfs->sb->sb_header.mh_magic) != GFS2_MAGIC) {
|
|
Packit |
6ef888 |
fprintf(stderr, _("Device does not contain a GFS or GFS2 file system\n"));
|
|
Packit |
6ef888 |
tfs->sb = NULL;
|
|
Packit |
6ef888 |
free(block);
|
|
Packit |
6ef888 |
return EX_IOERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
/* Ensure that table and proto are NULL terminated */
|
|
Packit |
6ef888 |
tfs->sb->sb_lockproto[GFS2_LOCKNAME_LEN - 1] = '\0';
|
|
Packit |
6ef888 |
tfs->sb->sb_locktable[GFS2_LOCKNAME_LEN - 1] = '\0';
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
static int is_gfs2(const struct tunegfs2 *tfs)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
return be32_to_cpu(tfs->sb->sb_fs_format) == GFS2_FORMAT_FS;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int print_super(const struct tunegfs2 *tfs)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
printf(_("File system volume name: %s\n"), tfs->sb->sb_locktable);
|
|
Packit |
6ef888 |
#ifdef GFS2_HAS_UUID
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
char readable_uuid[36+1];
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
uuid_unparse(tfs->sb->sb_uuid, readable_uuid);
|
|
Packit |
6ef888 |
printf(_("File system UUID: %s\n"), readable_uuid);
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
#endif
|
|
Packit |
6ef888 |
printf( _("File system magic number: 0x%X\n"), be32_to_cpu(tfs->sb->sb_header.mh_magic));
|
|
Packit |
6ef888 |
printf(_("Block size: %d\n"), be32_to_cpu(tfs->sb->sb_bsize));
|
|
Packit |
6ef888 |
printf(_("Block shift: %d\n"), be32_to_cpu(tfs->sb->sb_bsize_shift));
|
|
Packit |
6ef888 |
printf(_("Root inode: %llu\n"), (unsigned long long)be64_to_cpu(tfs->sb->sb_root_dir.no_addr));
|
|
Packit |
6ef888 |
if (is_gfs2(tfs))
|
|
Packit |
6ef888 |
printf(_("Master inode: %llu\n"), (unsigned long long)be64_to_cpu(tfs->sb->sb_master_dir.no_addr));
|
|
Packit |
6ef888 |
printf(_("Lock protocol: %s\n"), tfs->sb->sb_lockproto);
|
|
Packit |
6ef888 |
printf(_("Lock table: %s\n"), tfs->sb->sb_locktable);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int write_super(const struct tunegfs2 *tfs)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int n;
|
|
Packit |
6ef888 |
n = pwrite(tfs->fd, tfs->sb, GFS2_DEFAULT_BSIZE, tfs->sb_start);
|
|
Packit |
6ef888 |
if (n < 0) {
|
|
Packit |
6ef888 |
perror("write_super: pwrite");
|
|
Packit |
6ef888 |
return EX_IOERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int change_uuid(struct tunegfs2 *tfs, const char *str)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
#ifdef GFS2_HAS_UUID
|
|
Packit |
6ef888 |
uuid_t uuid;
|
|
Packit |
6ef888 |
int status;
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
status = uuid_parse(str, uuid);
|
|
Packit |
6ef888 |
if (status == 0)
|
|
Packit |
6ef888 |
uuid_copy(tfs->sb->sb_uuid, uuid);
|
|
Packit |
6ef888 |
return status;
|
|
Packit |
6ef888 |
#else
|
|
Packit |
6ef888 |
fprintf(stderr, _("UUID support unavailable in this build\n"));
|
|
Packit |
6ef888 |
return 1;
|
|
Packit |
6ef888 |
#endif
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int change_lockproto(struct tunegfs2 *tfs, const char *lockproto)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
int l = strlen(lockproto);
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (l >= GFS2_LOCKNAME_LEN) {
|
|
Packit |
6ef888 |
fprintf(stderr, _("Invalid lock protocol: %s\n"), _("too long"));
|
|
Packit |
6ef888 |
return EX_DATAERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (strncmp(lockproto, "lock_dlm", 8) &&
|
|
Packit |
6ef888 |
strncmp(lockproto, "lock_nolock", 11)) {
|
|
Packit |
6ef888 |
fprintf(stderr, _("Invalid lock protocol: %s\n"), lockproto);
|
|
Packit |
6ef888 |
return EX_DATAERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
memset(tfs->sb->sb_lockproto, '\0', GFS2_LOCKNAME_LEN);
|
|
Packit |
6ef888 |
strncpy(tfs->sb->sb_lockproto, lockproto, l);
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
int change_locktable(struct tunegfs2 *tfs, const char *locktable)
|
|
Packit |
6ef888 |
{
|
|
Packit |
6ef888 |
const char *errpre = _("Invalid lock table:");
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (strlen(locktable) >= GFS2_LOCKNAME_LEN) {
|
|
Packit |
6ef888 |
fprintf(stderr, "%s %s\n", errpre, _("too long"));
|
|
Packit |
6ef888 |
return EX_DATAERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
if (strcmp(tfs->sb->sb_lockproto, "lock_dlm") == 0) {
|
|
Packit |
6ef888 |
char *fsname = strchr(locktable, ':');
|
|
Packit |
6ef888 |
if (fsname == NULL) {
|
|
Packit |
6ef888 |
fprintf(stderr, "%s %s\n", errpre, _("missing colon"));
|
|
Packit |
6ef888 |
return EX_DATAERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (strlen(++fsname) > 30) {
|
|
Packit |
6ef888 |
fprintf(stderr, "%s %s\n", errpre, _("file system name is too long"));
|
|
Packit |
6ef888 |
return EX_DATAERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
if (strchr(fsname, ':')) {
|
|
Packit |
6ef888 |
fprintf(stderr, "%s %s\n", errpre, _("contains more than one colon"));
|
|
Packit |
6ef888 |
return EX_DATAERR;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|
|
Packit |
6ef888 |
strcpy(tfs->sb->sb_locktable, locktable);
|
|
Packit |
6ef888 |
return 0;
|
|
Packit |
6ef888 |
}
|
|
Packit |
6ef888 |
|