From: Anand Jain <anand.j...@oracle.com>

Moved from hash method of determining the FS changes to the transaction
record id method

Signed-off-by: Anand Jain <anand.j...@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

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to