2009/11/27 Ryusuke Konishi <[email protected]>:
> Hi!
> On Fri, 27 Nov 2009 15:21:06 +0100, David Smid <[email protected]> wrote:
>> Hi,
>>
>> I have two nilfs2 partitions and want to set different protection period for
>> each of them. I know nilfs_cleanerd has an option -p which allows to override
>> the protection period but using it would require to mount both partitions and
>> launch their cleaner daemons manually or within a script.
>> Since I want to use fstab I had to implement this option as a mount.nilfs2
>> extra
>> option.
>>
>> Not much was done to the kernel module: it just had to accept 'pp=' as a
>> valid
>> mount option.
>> mount.nilfs2 was modified to parse this option and its value and to pass it
>> to
>> nilfs_cleanerd command line.
>>
>> See the patches.
>>
>>
>> Regards,
>>
>> David Smid
>
> Thank you for the patches.
> I understood your intention.
>
> One comment. I don't like the dummy option is added to the kernel
> code because protection_period is entirely independent with it.
>
> Can you modify the patch so that mount.nilfs2 gets out the pp option
> from the string passed to the mount system call?
>
> A ready-made function, change_opt() would be available for that
> purpose.
>
> (only from extra_opts; mtab should include it to keep the value for
> cleanerd_ctl, of course)
>
> And, please inline patches in the mail; this makes it easy to comment
> on them.
>
> Thanks,
> Ryusuke Konishi
>
Thanks you for your valuable comments.
You are right, of course. No kernel code changes are needed.
Here is my take #2.
David
--- sbin/mount/cleaner_ctl.c.mount_pp_opt 2009-07-19 16:53:00.000000000
+0200
+++ sbin/mount/cleaner_ctl.c 2009-11-28 21:40:38.000000000 +0100
@@ -45,6 +45,7 @@
const char cleanerd[] = "/sbin/" CLEANERD_NAME;
const char cleanerd_nofork_opt[] = "-n";
+const char cleanerd_protperiod_opt[] = "-p";
extern char *progname;
@@ -54,12 +55,13 @@
return (kill(pid, 0) == 0);
}
-int start_cleanerd(const char *device, const char *mntdir, pid_t *ppid)
+int start_cleanerd(const char *device, const char *mntdir, unsigned
long protperiod, pid_t *ppid)
{
- const char *dargs[5];
+ const char *dargs[7];
struct stat statbuf;
int i = 0;
int res;
+ char buf[256];
if (stat(cleanerd, &statbuf) != 0) {
error(_("Warning: %s not found"), CLEANERD_NAME);
@@ -80,6 +82,11 @@
}
dargs[i++] = cleanerd;
dargs[i++] = cleanerd_nofork_opt;
+ if (protperiod != ULONG_MAX) {
+ dargs[i++] = cleanerd_protperiod_opt;
+ snprintf(buf, sizeof(buf), "%lu", protperiod);
+ dargs[i++] = buf;
+ }
dargs[i++] = device;
dargs[i++] = mntdir;
dargs[i] = NULL;
--- sbin/mount/mount.nilfs2.h.mount_pp_opt 2009-07-19 16:53:00.000000000
+0200
+++ sbin/mount/mount.nilfs2.h 2009-11-28 20:37:33.000000000 +0100
@@ -13,12 +13,13 @@
#define NILFS2_FS_NAME "nilfs2"
#define CLEANERD_NAME "nilfs_cleanerd"
#define PIDOPT_NAME "gcpid"
+#define PPOPT_NAME "pp"
#define CLEANERD_WAIT_RETRY_COUNT 3
#define CLEANERD_WAIT_RETRY_INTERVAL 2 /* in seconds */
-extern int start_cleanerd(const char *, const char *, pid_t *);
+extern int start_cleanerd(const char *, const char *, unsigned long, pid_t *);
extern int stop_cleanerd(const char *, pid_t);
extern int check_cleanerd(const char *, pid_t);
--- sbin/mount/umount.nilfs2.c.mount_pp_opt 2009-07-19 16:53:00.000000000
+0200
+++ sbin/mount/umount.nilfs2.c 2009-11-28 21:40:23.000000000 +0100
@@ -69,6 +69,9 @@
const char gcpid_opt_fmt[] = PIDOPT_NAME "=%d";
typedef int gcpid_opt_t;
+const char pp_opt_fmt[] = PPOPT_NAME "=%lu";
+typedef unsigned long pp_opt_t;
+
struct umount_options {
int flags;
int force;
@@ -317,6 +320,7 @@
int res, alive = 0;
const char *loopdev;
pid_t pid;
+ pp_opt_t prot_period;
if (streq (node, "/") || streq (node, "root"))
nomtab++;
@@ -349,7 +353,10 @@
progname, spec);
}
} else if (alive && !check_cleanerd(spec, pid)) {
- if (start_cleanerd(spec, node, &pid) == 0) {
+ if (find_opt(mc->m.mnt_opts, pp_opt_fmt, &prot_period)
< 0)
+ prot_period = ULONG_MAX;
+
+ if (start_cleanerd(spec, node, prot_period, &pid) == 0)
{
if (verbose)
printf(_("%s: restarted %s(pid=%d)\n"),
progname, CLEANERD_NAME,
--- sbin/mount/mount.nilfs2.c.mount_pp_opt 2009-07-19 16:53:00.000000000
+0200
+++ sbin/mount/mount.nilfs2.c 2009-11-28 21:39:27.000000000 +0100
@@ -71,6 +71,9 @@
const char gcpid_opt_fmt[] = PIDOPT_NAME "=%d";
typedef int gcpid_opt_t;
+const char pp_opt_fmt[] = PPOPT_NAME "=%lu";
+typedef unsigned long pp_opt_t;
+
struct mount_options {
char *fstype;
char *opts;
@@ -225,6 +228,17 @@
*opts = newopts;
}
+static void update_pp_opt(char **opts, pp_opt_t protection_period)
+{
+ char buf[256], *newopts;
+ pp_opt_t oldpp;
+
+ snprintf(buf, sizeof(buf), pp_opt_fmt, protection_period);
+ newopts = change_opt(*opts, pp_opt_fmt, &oldpp, buf);
+ my_free(*opts);
+ *opts = newopts;
+}
+
static char *fix_extra_opts_string(const char *extra_opts, pid_t gcpid)
{
char buf[256];
@@ -408,9 +422,14 @@
do_mount_one(struct nilfs_mount_info *mi, const struct mount_options *mo)
{
int res, errsv;
+ char *exopts;
+ pp_opt_t prot_period;
+
+ prot_period = ULONG_MAX;
+ exopts = change_opt(mo->extra_opts, pp_opt_fmt, &prot_period, "");
res = mount(mi->device, mi->mntdir, fstype, mo->flags & ~MS_NOSYS,
- mo->extra_opts);
+ exopts);
if (!res)
goto out;
@@ -429,11 +448,13 @@
goto out;
if (check_mtab()) {
/* Restarting cleaner daemon */
- if (start_cleanerd(mi->device, mi->mntdir, &mi->gcpid) == 0) {
+ if (start_cleanerd(mi->device, mi->mntdir, prot_period,
&mi->gcpid) == 0) {
if (verbose)
printf(_("%s: restarted %s\n"),
progname, CLEANERD_NAME);
update_gcpid_opt(&mi->optstr, mi->gcpid);
+ if (prot_period != ULONG_MAX)
+ update_pp_opt(&mi->optstr, prot_period);
update_mtab_entry(mi->device, mi->mntdir, fstype,
mi->optstr, 0, 0, !mi->mounted);
} else {
@@ -443,6 +464,7 @@
} else
printf(_("%s not restarted\n"), CLEANERD_NAME);
out:
+ my_free(exopts);
return res;
}
@@ -452,6 +474,7 @@
pid_t pid = (mi->type == RW2RW_REMOUNT) ? mi->gcpid : 0;
char *exopts;
int rungc;
+ pp_opt_t prot_period;
rungc = !(mo->flags & MS_RDONLY) && !(mo->flags & MS_BIND) &&
(mi->type != RW2RW_REMOUNT || mi->gcpid == 0);
@@ -461,7 +484,10 @@
return;
}
if (rungc) {
- if (start_cleanerd(mi->device, mi->mntdir, &pid) < 0)
+ if (find_opt(mo->extra_opts, pp_opt_fmt, &prot_period) < 0)
+ prot_period = ULONG_MAX;
+
+ if (start_cleanerd(mi->device, mi->mntdir, prot_period, &pid) <
0)
error(_("%s aborted"), CLEANERD_NAME);
else if (verbose)
printf(_("%s: started %s\n"), progname, CLEANERD_NAME);
--- man/mount.nilfs2.8.mount_pp_opt 2009-07-19 16:53:00.000000000 +0200
+++ man/mount.nilfs2.8 2009-11-28 21:51:23.000000000 +0100
@@ -103,6 +103,12 @@
remount the file system read-only, or panic and halt the system.) The
default is continue.
.TP
+.BR pp=\fP\fIprotection-period\fP
+Specify the \fIprotection-period\fP for the cleaner daemon (in
+seconds). nilfs_cleanerd never deletes recent checkpoints whose
+elapsed time from its creation is smaller than
+\fIprotection-period\fP.
+.TP
.BR order=relaxed " / " order=strict
Specify order semantics for file data. Metadata is always written to
follow the POSIX semantics about the order of filesystem operations.
_______________________________________________
users mailing list
[email protected]
https://www.nilfs.org/mailman/listinfo/users