Commit 954ba48d authored by Cyrill Gorcunov's avatar Cyrill Gorcunov Committed by Pavel Emelyanov

zdtm: Add filesystem specific helpers

In particular we have to find out if we're
running on btrfs filesystem for proper device
number mangling.
Signed-off-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Acked-by: 's avatarAndrew Vagin <avagin@odin.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent ec31527b
...@@ -6,7 +6,7 @@ CFLAGS += $(USERCFLAGS) ...@@ -6,7 +6,7 @@ CFLAGS += $(USERCFLAGS)
LIBDIR = . LIBDIR = .
LIB = libzdtmtst.a LIB = libzdtmtst.a
LIBSRC = datagen.c msg.c parseargs.c test.c streamutil.c lock.c ns.c tcp.c LIBSRC = datagen.c msg.c parseargs.c test.c streamutil.c lock.c ns.c tcp.c fs.c
LIBOBJ = $(LIBSRC:%.c=%.o) LIBOBJ = $(LIBSRC:%.c=%.o)
LIBDEP = $(LIBSRC:%.c=%.d) LIBDEP = $(LIBSRC:%.c=%.d)
......
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>
#include <errno.h>
#include <unistd.h>
#include <limits.h>
#include "zdtmtst.h"
#include "fs.h"
mnt_info_t *mnt_info_alloc(void)
{
mnt_info_t *m = malloc(sizeof(*m));
if (m)
memset(m, 0, sizeof(*m));
return m;
}
void mnt_info_free(mnt_info_t **m)
{
if (m && *m) {
free(*m);
*m = NULL;
}
}
mnt_info_t *get_cwd_mnt_info(void)
{
int mnt_id, parent_mnt_id;
unsigned int kmaj, kmin;
char str[1024], *cwd;
int ret;
FILE *f;
mnt_info_t *m = NULL;
char mountpoint[PATH_MAX];
char root[PATH_MAX];
char *fsname = NULL;
size_t len = 0, best_len = 0;
f = fopen("/proc/self/mountinfo", "r");
if (!f)
return NULL;
cwd = get_current_dir_name();
if (!cwd)
goto err;
m = mnt_info_alloc();
if (!m)
goto err;
while (fgets(str, sizeof(str), f)) {
char *hyphen = strchr(str, '-');
ret = sscanf(str, "%i %i %u:%u %s %s",
&mnt_id, &parent_mnt_id,
&kmaj, &kmin,
root, mountpoint);
if (ret != 6 || !hyphen)
goto err;
ret = sscanf(hyphen + 1, " %ms", &fsname);
if (ret != 1)
goto err;
len = strlen(mountpoint);
if (!strncmp(mountpoint, cwd, len)) {
if (len > best_len) {
best_len = len;
m->mnt_id = mnt_id;
m->parent_mnt_id = parent_mnt_id;
m->s_dev = MKKDEV(kmaj, kmin);
strncpy(m->root, root, sizeof(m->root));
strncpy(m->mountpoint, mountpoint, sizeof(m->mountpoint));
strncpy(m->fsname, fsname, sizeof(m->fsname));
}
}
free(fsname);
fsname = NULL;
}
out:
free(cwd);
fclose(f);
return m;
err:
mnt_info_free(&m);
goto out;
}
#ifndef ZDTM_FS_H_
#define ZDTM_FS_H_
#define _BSD_SOURCE
#include <sys/types.h>
#include <limits.h>
#define KDEV_MINORBITS 20
#define KDEV_MINORMASK ((1UL << KDEV_MINORBITS) - 1)
#define MKKDEV(ma, mi) (((ma) << KDEV_MINORBITS) | (mi))
static inline unsigned int kdev_major(unsigned int kdev)
{
return kdev >> KDEV_MINORBITS;
}
static inline unsigned int kdev_minor(unsigned int kdev)
{
return kdev & KDEV_MINORMASK;
}
static inline dev_t kdev_to_odev(unsigned int kdev)
{
/*
* New kernels encode devices in a new form.
* See kernel's fs/stat.c for details, there
* choose_32_64 helpers which are the key.
*/
unsigned major = kdev_major(kdev);
unsigned minor = kdev_minor(kdev);
return makedev(major, minor);
}
typedef struct {
int mnt_id;
int parent_mnt_id;
unsigned int s_dev;
char root[PATH_MAX];
char mountpoint[PATH_MAX];
char fsname[64];
} mnt_info_t;
extern mnt_info_t *mnt_info_alloc(void);
extern void mnt_info_free(mnt_info_t **m);
extern mnt_info_t *get_cwd_mnt_info(void);
#endif /* ZDTM_FS_H_ */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment