Date: Wed, 12 Oct 2016 05:29:48 +0000 From: Hongjiang Zhang <honzhan@microsoft.com> To: =?utf-8?B?RWR3YXJkIFRvbWFzeiBOYXBpZXJhxYJh?= <trasz@FreeBSD.org> Cc: "freebsd-fs@freebsd.org" <freebsd-fs@freebsd.org>, Mateusz Guzik <mjguzik@gmail.com> Subject: RE: ufs freeze does not work Message-ID: <CY1PR03MB151713BEF58B75BB4850F578B5DD0@CY1PR03MB1517.namprd03.prod.outlook.com> In-Reply-To: <20160629043203.GA82400@brick> References: <CO2PR03MB2215FAA1AB86A669039B9540B5210@CO2PR03MB2215.namprd03.prod.outlook.com> <20160628065432.GA20716@brick> <SN2PR03MB2224903F61C7DD576EDDB05DB5220@SN2PR03MB2224.namprd03.prod.outlook.com> <20160628185523.GA82035@brick> <20160628195731.GA21323@dft-labs.eu> <20160629043203.GA82400@brick>
next in thread | previous in thread | raw e-mail | index | archive | help
[-- Attachment #1 --]
Hi Edward,
I have another question about UFS suspend. Shall I call "sync" before freezing the fs? See it in my code.
Another question is do you think it is necessary for FreeBSD to provide a such tool? Is there any stat tool for user to know which file partition is freezed?
sync(); // Is this necessary?
error = ioctl(fso, UFSSUSPEND, &statfsp->f_fsid);
Thanks
Hongjiang Zhang
-----Original Message-----
From: Edward Tomasz Napierała [mailto:etnapierala@gmail.com] On Behalf Of Edward Tomasz Napierala
Sent: Wednesday, June 29, 2016 12:32 PM
To: Mateusz Guzik <mjguzik@gmail.com>
Cc: Hongjiang Zhang <honzhan@microsoft.com>; freebsd-fs@freebsd.org
Subject: Re: ufs freeze does not work
On 0628T2157, Mateusz Guzik wrote:
> On Tue, Jun 28, 2016 at 08:55:23PM +0200, Edward Tomasz Napierała wrote:
> > As I said, the suspension is released when the ufssuspend file
> > descriptor gets closed - which is what happens when the calling
> > process exits. It's a protection mechanism, to avoid the situation
> > where the process malfunction (eg a crash) would leave the system in unrecoverable (suspended) state.
> >
> > You probably want your process to just execute another one, and wait
> > until it exits.
> >
>
> The example with freeze -f strongly hints this is supposed to work as
> a drop in replacement for linux scripts.
>
> As such, maybe ufs should grow another operation which does not
> automagically unfreeze.
I'm not sure it's a good idea to provide an inferior mechanism just for backward compatibility with Linux. Especially given how easy it is to do it properly, modeling the utility after eg lockf(1).
[-- Attachment #2 --]
#include <string.h>
#include <stdio.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/ucred.h>
#include <sys/mount.h>
#include <sys/types.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <err.h>
#include <fcntl.h>
#include <ufs/ffs/fs.h>
#define _PATH_UFSSUSPEND "/dev/ufssuspend"
#define UNDEF_FREEZE_THAW (0)
#define FREEZE (1)
#define THAW (2)
#define SLEEP_TIME (10)
static int
test_write_tmp(const char* p)
{
int ret = 0;
char data[] = "abcdefghij";
char filename[64];
const char *test_file = "test_freeze";
if (p != NULL) {
snprintf(filename, sizeof(filename), "%s/%s", p, test_file);
} else {
snprintf(filename, sizeof(filename), "/tmp/%s", test_file);
}
FILE *fp = fopen(filename, "rw+");
if (!fp) {
ret = 1;
printf("Fail to open");
goto error;
}
int len = 5;
int writelen = fwrite(data, sizeof(char), len, fp);
if (writelen != len) {
ret = 2;
printf("Fail to write the %d character\n", len);
goto error;
}
fclose(fp);
return 0;
error:
printf("error in test_write_tmp\n");
return ret;
}
static void freeze(const char* partition, int duration)
{
struct statfs *mntbuf, *statfsp;
int mntsize;
int fso;
int error = 0;
int i;
int write_test_rtn = 0;
const char *dev = "/dev";
fso = open(_PATH_UFSSUSPEND, O_RDWR);
if (fso == -1)
err(1, "unable to open %s", _PATH_UFSSUSPEND);
/*
* First check the mounted filesystems.
*/
mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
if (mntsize == 0)
return;
printf("mnt size: %d\n", mntsize);
for(i = mntsize - 1; i >= 0; --i)
{
statfsp = &mntbuf[i];
printf("fstype: %s, on '%s' from '%s'\n",
statfsp->f_fstypename,
statfsp->f_mntonname, statfsp->f_mntfromname);
if (strncmp(statfsp->f_mntonname, dev, strlen(dev)) == 0) {
continue; /* skip to freeze '/dev' */
} else if (statfsp->f_flags & MNT_RDONLY) {
continue; /* skip to freeze RDONLY partition */
} else if (strncmp(statfsp->f_fstypename, "ufs", 3) != 0) {
continue; /* only UFS can be freezed */
}
sync();
if ((partition == NULL && strcmp("/", statfsp->f_mntonname) == 0) ||
(partition != NULL && strncmp(statfsp->f_mntonname,
partition, strlen(partition)) == 0)) {
if (partition == NULL) {
partition = statfsp->f_mntonname;
}
printf("begin to suspend on '%s'\n", partition);
error = ioctl(fso, UFSSUSPEND, &statfsp->f_fsid);
if (error != 0) {
printf("error: %d\n",errno);
} else {
printf("Successfully suspend filesystem\n");
}
break;
}
}
if (error == 0) {
sleep(duration); /* how long time to freeze */
write_test_rtn = test_write_tmp(partition);
if (!write_test_rtn) {
printf("Successfully write something\n");
}
}
close(fso); /* Stop freeze once the file handle is closed */
}
static void usage(const char* cmd) {
fprintf(stderr, "%s -f : freeze the root filesystem\n"
/* " -t : thaw the filesystem\n" */
" -F <partition> : freeze the specified partition\n"
" -d <duration> : specify the duration (s) for freezing\n",
cmd);
exit(1);
}
int main(int argc, char* argv[]) {
int ch;
int freeze_thaw = UNDEF_FREEZE_THAW;
const char* partition = NULL;
int freeze_dur = SLEEP_TIME;
while ((ch = getopt(argc, argv, "F:d:f")) != -1) {
switch (ch) {
case 'f':
/* Run as regular process for debugging purpose. */
freeze_thaw = FREEZE;
break;
case 'F':
freeze_thaw = FREEZE;
partition = optarg;
break;
case 'd':
freeze_dur = (int)strtol(optarg, NULL, 10);
break;
default:
break;
}
}
if (freeze_thaw == FREEZE) {
freeze(partition, freeze_dur);
} else {
usage(argv[0]);
}
return 0;
}
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?CY1PR03MB151713BEF58B75BB4850F578B5DD0>
