From: Anand jain <Anand.Jain@oracle.com>
To: linux-btrfs@vger.kernel.org
Cc: chris.mason@oracle.com, hugo@carfax.org.uk,
Anand Jain <Anand.Jain@oracle.com>
Subject: [PATCH 2/2] Use transaction id to determin if there is any change in the subvol
Date: Tue, 6 Mar 2012 15:56:11 +0800 [thread overview]
Message-ID: <1331020571-30261-2-git-send-email-Anand.Jain@oracle.com> (raw)
In-Reply-To: <1331020571-30261-1-git-send-email-Anand.Jain@oracle.com>
From: Anand Jain <Anand.Jain@oracle.com>
Moved from hash method of determining the FS changes to the transaction
record id method
Signed-off-by: Anand Jain <Anand.Jain@oracle.com>
---
autosnap.c | 106 ++++++++++++++++++++++++++++++++++++++----------------------
autosnap.h | 4 +--
2 files changed, 70 insertions(+), 40 deletions(-)
diff --git a/autosnap.c b/autosnap.c
index beddf68..1adaf01 100644
--- a/autosnap.c
+++ b/autosnap.c
@@ -45,7 +45,7 @@
/* during run time if not the below we use "/var/spool/cron"; */
char cron_path[]="/var/spool/cron/crontabs";
char autosnap_conf_file[]="/etc/autosnap/config";
-char tmp_file[]="/etc/autosnap/tmpfile";
+//char tmp_file[]="/etc/autosnap/tmpfile";
/* Take a snapshot with the default dest and adds attributes */
@@ -59,10 +59,10 @@ int do_autosnap_now(int argc, char **argv)
char **ap;
char subvol[BTRFS_VOL_NAME_MAX];
char sspath[BTRFS_VOL_NAME_MAX + 128];
- char tag[100];
- char new_hash[65];
+ char tag[TAG_MAX_LEN];
+ u64 cur_tranid = 0;
+ u64 ss_tranid = 0;
char *mnt;
- FILE *fp;
u8 fsid[BTRFS_FSID_SIZE];
struct stat sb;
struct rpolicy_cfg rp;
@@ -101,6 +101,7 @@ int do_autosnap_now(int argc, char **argv)
return -1;
fd = open_file_or_dir(mnt);
get_fsid(fd,&fsid[0]);
+ close(fd);
if ((res = read_config(subvol+strlen(mnt),tag,&rp,NULL,&fsid[0])) == 1) {
fprintf(stderr,"need to run autosnap enable for this subvol and tag pair\n");
return 1;
@@ -109,28 +110,46 @@ int do_autosnap_now(int argc, char **argv)
return 1;
}
+ /* Check if there is any change in the FS by comparing the transaction id*/
+ if (strcmp(rp.idcal, "older") == 0 ) {
+ /* Sync Subvol*/
+ a[1] = subvol;
+ ap = a;
+ res = do_fssync(1, ap);
+ if(res != 0) {
+ return -1;
+ }
+ fd = open_file_or_dir(subvol);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: can't access '%s'\n", subvol);
+ return -1;
+ }
+ res = find_updated_files(fd, 0, -1, &cur_tranid);
+ close(fd);
+ if (res)
+ return -1;
+
+ if((stat(rp.last_ss, &sb) == 0) && (rp.last_ss_tranid == cur_tranid)) {
+ printf("FS is identical to the last snapshot. Aborting.\n");
+ return -1;
+ }
+ }
+
if ( take_autosnap(subvol, tag, sspath) !=0 )
return -1;
- if (strcmp(rp.idcal, "older") == 0 ) {
- fp = fopen(tmp_file, "w");
- tree_scan(sspath, fp);
- fclose(fp);
- get_sha256(tmp_file, new_hash);
- if((stat(rp.last_ss, &sb) == 0) && (strcmp(rp.last_ss_hash,new_hash) == 0)) {
- printf("Newer snapshot is identical to the previous snapshot, deleting the newer\n");
- a[1] = sspath;
- ap = a;
- res = do_delete_subvolume(2,ap);
- if(res)
- printf("do_delete_subvolume failed %d\n",res);
- } else {
- /* hash does not match so keep the new snasphot OR
- Last snapshot was deleted. */
- update_last_hash(subvol+strlen(mnt),tag,&fsid[0],sspath,new_hash);
- }
- unlink(tmp_file);
+ fd = open_file_or_dir(sspath);
+ if (fd < 0) {
+ fprintf(stderr, "ERROR: can't access '%s'\n", sspath);
+ return -1;
}
+ res = find_updated_files(fd, 0, -1, &ss_tranid);
+ close(fd);
+ if (res)
+ return -1;
+
+ /* tranid does not match or Last snapshot was deleted. go ahead*/
+ update_last_tranid(subvol+strlen(mnt),tag,&fsid[0],sspath,ss_tranid);
#if 0
/* Un-def this when we have synchronous snapshot delete */
@@ -141,7 +160,8 @@ int do_autosnap_now(int argc, char **argv)
if (rp.rpval != -1) {
res = chk_retain_bynum(subvol, rp.rpval, tag);
if(res != 0 ) {
- fprintf(stderr,"Error: Check for the retainable subvol failed %d\n",res);
+ fprintf(stderr,"Error: Check for the retainable subvol failed %d\n",
+ res);
return -1;
}
}
@@ -457,7 +477,8 @@ int do_autosnap_enable(int argc, char **argv)
case 'm':
fcnt++;
if ((atoi(optarg) > 60) || (atoi(optarg) < 1)) {
- fprintf(stderr, "Value for option -m: Minutes should be between 1 to 60\n");
+ fprintf(stderr, "Value for option -m: Minutes should be between\
+ 1 to 60\n");
founderr++;
} else {
sprintf(freq, "*/%s * * * *", optarg);
@@ -497,7 +518,8 @@ int do_autosnap_enable(int argc, char **argv)
rcnt++;
retcnt = atoi(optarg);
if (retcnt <= 0) {
- fprintf(stderr, "Value for option -c: Should be a number, snapshots to retain\n");
+ fprintf(stderr, "Value for option -c: Should be a number,\
+ snapshots to retain\n");
founderr++;
}
rpval = retcnt;
@@ -505,12 +527,14 @@ int do_autosnap_enable(int argc, char **argv)
case 'n':
strcpy(idcal,optarg);
if (!((strcmp(idcal, "disable") ==0) || (strcmp(idcal, "older") == 0))) {
- fprintf(stderr, "Error: parameter %s should be one of disable|older\n",idcal);
+ fprintf(stderr, "Error: parameter %s should be one of disable|older\n",
+ idcal);
founderr++;
}
break;
case '?':
- if (optopt == 't' || optopt == 'm' || optopt == 'D' || optopt == 'c' || optopt == 'D')
+ if (optopt == 't' || optopt == 'm' || optopt == 'D' || optopt == 'c'\
+ || optopt == 'D')
fprintf (stderr, "Option -%c requires an argument.\n", optopt);
else if (isprint (optopt))
fprintf (stderr, "Unknown option `-%c'.\n", optopt);
@@ -1050,7 +1074,7 @@ int read_config(char *subvol, char *tag, struct rpolicy_cfg *retcfg, struct rpol
strcpy(cur->tag, rcfg.tag);
strcpy(cur->freq, rcfg.freq);
strcpy(cur->idcal, rcfg.idcal);
- strcpy(cur->last_ss_hash, rcfg.last_ss_hash);
+ cur->last_ss_tranid = rcfg.last_ss_tranid;
strcpy(cur->last_ss, rcfg.last_ss);
for(i=0; i<BTRFS_FSID_SIZE; i++)
cur->fsid[i]= rcfg.fsid[i];
@@ -1065,7 +1089,7 @@ int read_config(char *subvol, char *tag, struct rpolicy_cfg *retcfg, struct rpol
strcpy(retcfg->tag, rcfg.tag);
strcpy(retcfg->freq, rcfg.freq);
strcpy(retcfg->idcal, rcfg.idcal);
- strcpy(retcfg->last_ss_hash, rcfg.last_ss_hash);
+ retcfg->last_ss_tranid = rcfg.last_ss_tranid;
strcpy(retcfg->last_ss, rcfg.last_ss);
for(i=0; i<BTRFS_FSID_SIZE; i++)
retcfg->fsid[i] = rcfg.fsid[i];
@@ -1150,7 +1174,8 @@ int delete_config(char *subvol, char *tag, u8 *fsid)
break;
}
} else {
- if((strcmp(cur->subvol, subvol) == 0) && (memcmp(&(cur->fsid),fsid,BTRFS_FSID_SIZE) == 0)) {
+ if((strcmp(cur->subvol, subvol) == 0) &&\
+ (memcmp(&(cur->fsid),fsid,BTRFS_FSID_SIZE) == 0)) {
if(head == cur)
head = cur->next;
prev->next = cur->next;
@@ -1170,8 +1195,8 @@ int delete_config(char *subvol, char *tag, u8 *fsid)
return 0;
}
-/* maintain the last snapshot hash info so that identical snapshots are not taken */
-int update_last_hash(char *subvol, char *tag, u8 *fsid,char *last_ss, char *hash)
+/* maintain the trans id when last snapshot occurred */
+int update_last_tranid(char *subvol, char *tag, u8 *fsid,char *last_ss, u64 tranid)
{
int res;
struct rpolicy_cfg *head = NULL;
@@ -1189,7 +1214,7 @@ int update_last_hash(char *subvol, char *tag, u8 *fsid,char *last_ss, char *hash
while(cur != NULL) {
if((strcmp(cur->subvol, subvol) == 0) && (strcmp(cur->tag, tag) == 0) &&
(memcmp(&cur->fsid,fsid,BTRFS_FSID_SIZE)==0)) {
- strcpy(cur->last_ss_hash,hash);
+ cur->last_ss_tranid = tranid;
strcpy(cur->last_ss, last_ss);
break;
}
@@ -1223,11 +1248,15 @@ int write_config(char *subvol, int rpval, char *freq, int diffsz, char *tag, cha
return 1;
}
+ rcfg.last_ss_tranid = 0;
+ strcpy(rcfg.last_ss, "");
+
/* need to find if user is modifying an exisiting entry or creating new*/
while((ret = read(fp, &rcfg, sz)) > 0) {
- //if((strcmp(rcfg.subvol, subvol) == 0) && (strcmp(rcfg.tag, tag) == 0)) break;
if((strcmp(rcfg.subvol, subvol) == 0) && (strcmp(rcfg.tag, tag) == 0) &&\
- (memcmp(&rcfg.fsid,fsid,BTRFS_FSID_SIZE) == 0)) break;
+ (memcmp(&rcfg.fsid,fsid,BTRFS_FSID_SIZE) == 0)) {
+ break;
+ }
offset = offset + sz;
memset(&rcfg,0,sz);
}
@@ -1247,8 +1276,6 @@ int write_config(char *subvol, int rpval, char *freq, int diffsz, char *tag, cha
strcpy(rcfg.subvol, subvol);
strcpy(rcfg.tag, tag);
strcpy(rcfg.idcal, idcal);
- strcpy(rcfg.last_ss_hash, "");
- strcpy(rcfg.last_ss, "");
for(i=0;i<BTRFS_FSID_SIZE;i++)
rcfg.fsid[i] = *(fsid++);
@@ -1431,6 +1458,7 @@ int fs_used(char *mnt)
return (100 - res);
}
+#ifndef DELETE
/* generate the sha256 code for a given file */
int get_sha256(char *fpath, char *op)
{
@@ -1498,13 +1526,15 @@ int tree_scan( const char *path, FILE *fp)
entry->d_name,sb.st_mode,sb.st_nlink,sb.st_uid,sb.st_gid,\
ctime(&sb.st_mtime),ctime(&sb.st_ctime));
}
- if(!(S_ISREG(sb.st_mode)) && (strcmp(".",entry->d_name)) && (strcmp("..",entry->d_name))) {
+ if(!(S_ISREG(sb.st_mode)) && (strcmp(".",entry->d_name)) &&\
+ (strcmp("..",entry->d_name))) {
tree_scan( spath,fp);
}
}
closedir( dir);
return(0);
}
+#endif
/* obtain mnt from the subvol path */
int subvol_to_mnt(char *subvol, char **mnt)
diff --git a/autosnap.h b/autosnap.h
index dc126b6..2b4322c 100644
--- a/autosnap.h
+++ b/autosnap.h
@@ -45,7 +45,7 @@ struct rpolicy_cfg {
char freq[TAG_MAX_LEN];
char tag[TAG_MAX_LEN];
char idcal[50];
- char last_ss_hash[65];
+ u64 last_ss_tranid;
char last_ss[BTRFS_VOL_NAME_MAX];
int rpval;
int diffsz;
@@ -62,7 +62,7 @@ int get_fsid(int fd, u8 *fsidp);
int chk_fslimit(char *subvol);
char *find_oldest_snap(char *mnt, char *parent, char *tag);
int write_config(char *subvol, int rpval, char *freq, int diffsz, char *tag, char *idcal, u8 *fsid);
-int update_last_hash(char *subvol, char *tag, u8 *fsid,char *last_ss, char *hash);
+int update_last_tranid(char *subvol, char *tag, u8 *fsid,char *last_ss, u64 tranid);
int delete_config(char *subvol, char *tag, u8 *fsid);
int rewrite_config(struct rpolicy_cfg *cfg);
int read_config(char *subvol, char *tag, struct rpolicy_cfg *retcfg, struct rpolicy_cfg **head, u8 *fsid);
--
1.7.9.2.315.g25a78
next prev parent reply other threads:[~2012-03-06 7:56 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-29 2:59 [RFC] [PATCH] Add btrfs autosnap feature asj
2012-02-29 2:59 ` [PATCH] [RFC] " asj
2012-02-29 3:38 ` Anand Jain
2012-03-01 11:54 ` cwillu
2012-03-02 11:34 ` Arvin Schnell
2012-03-02 12:04 ` cwillu
2012-03-02 12:25 ` Sander
2012-03-05 6:51 ` Anand Jain
2012-03-05 7:07 ` Fajar A. Nugraha
2012-03-05 7:18 ` Arne Jansen
2012-03-05 10:21 ` Anand Jain
2012-03-05 10:28 ` cwillu
2012-03-01 13:23 ` Roman Mamedov
2012-03-06 7:56 ` [PATCH 1/2] Make find_updated_files to return value instead of printing Anand jain
2012-03-06 7:56 ` Anand jain [this message]
2012-03-06 9:07 ` [PATCH 2/2 v2] Use transaction id to determin if there is any change in the subvol Anand jain
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1331020571-30261-2-git-send-email-Anand.Jain@oracle.com \
--to=anand.jain@oracle.com \
--cc=chris.mason@oracle.com \
--cc=hugo@carfax.org.uk \
--cc=linux-btrfs@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).