Fossil SCM

Catch SIGINT during sync so that when pressing ctrl-c during a clone of a large repository it doesn't dispose of all the progress that was made during, thus enabling resume from an user interrupt. When the handler returns, the last sync will complete and then exit the loop.

andybradford 2023-11-30 04:01 clone-resume
Commit ad2e148541fe0716b534eab267cce993cb78e564b40c192b22d921143ffc3708
2 files changed +21 -7 +18
+21 -7
--- src/clone.c
+++ src/clone.c
@@ -18,10 +18,11 @@
1818
** This file contains code used to clone a repository
1919
*/
2020
#include "config.h"
2121
#include "clone.h"
2222
#include <assert.h>
23
+#include <signal.h>
2324
2425
/*
2526
** If there are public BLOBs that deltas from private BLOBs, then
2627
** undeltify the public BLOBs so that the private BLOBs may be safely
2728
** deleted.
@@ -282,33 +283,46 @@
282283
db_protect_pop();
283284
url_enable_proxy(0);
284285
clone_ssh_db_set_options();
285286
url_get_password_if_needed();
286287
g.xlinkClusterOnly = 1;
287
- while( nResumes++<3 && (nErr = client_sync(syncFlags,CONFIGSET_ALL,0,0)) ){
288
- fossil_warning("cloning encountered errors, trying again.");
289
- sqlite3_sleep(500);
288
+ while( nResumes++<3 && sync_interrupted()==0
289
+ && (nErr = client_sync(syncFlags,CONFIGSET_ALL,0,0))
290
+ ){
291
+ if( sync_interrupted()!=0 ){
292
+ fossil_warning("cloning encountered errors, trying again.");
293
+ sqlite3_sleep(500);
294
+ }
290295
}
291296
g.xlinkClusterOnly = 0;
292297
verify_cancel();
293298
if( nErr ){
294299
fossil_warning("server returned an error - clone incomplete");
300
+ }else if( sync_interrupted()==1 ){
301
+ fossil_warning("clone was interrupted");
295302
}else{
296303
db_unprotect(PROTECT_CONFIG);
297304
db_multi_exec("DELETE FROM config WHERE name = 'aux-clone-seqno';");
298305
db_protect_pop();
299306
}
300307
db_end_transaction(0);
301308
db_close(1);
302309
db_open_repository(zRepo);
310
+#if !defined(_WIN32)
311
+ signal(SIGINT, SIG_DFL);
312
+#endif
303313
}
304314
db_begin_transaction();
305315
if( db_exists("SELECT 1 FROM delta WHERE srcId IN phantom") ){
306
- fossil_warning("there are unresolved deltas -"
307
- " the clone is probably incomplete and unusable.\n"
308
- "It may be possible to resume the clone by running the"
309
- " same command.");
316
+ if( db_get_int("aux-clone-seqno",0)==0 ){
317
+ fossil_fatal("there are unresolved deltas -"
318
+ " the clone is probabaly incomplete and unusable.");
319
+ }
320
+ }
321
+ if( db_get_int("aux-clone-seqno",0)>0 ){
322
+ fossil_warning("Clone incomplete - it may be possible to resume the"
323
+ " clone by running the same command again.");
310324
}
311325
fossil_print("Rebuilding repository meta-data...\n");
312326
rebuild_db(1, 0);
313327
if( !noCompress ){
314328
int nDelta = 0;
315329
--- src/clone.c
+++ src/clone.c
@@ -18,10 +18,11 @@
18 ** This file contains code used to clone a repository
19 */
20 #include "config.h"
21 #include "clone.h"
22 #include <assert.h>
 
23
24 /*
25 ** If there are public BLOBs that deltas from private BLOBs, then
26 ** undeltify the public BLOBs so that the private BLOBs may be safely
27 ** deleted.
@@ -282,33 +283,46 @@
282 db_protect_pop();
283 url_enable_proxy(0);
284 clone_ssh_db_set_options();
285 url_get_password_if_needed();
286 g.xlinkClusterOnly = 1;
287 while( nResumes++<3 && (nErr = client_sync(syncFlags,CONFIGSET_ALL,0,0)) ){
288 fossil_warning("cloning encountered errors, trying again.");
289 sqlite3_sleep(500);
 
 
 
 
290 }
291 g.xlinkClusterOnly = 0;
292 verify_cancel();
293 if( nErr ){
294 fossil_warning("server returned an error - clone incomplete");
 
 
295 }else{
296 db_unprotect(PROTECT_CONFIG);
297 db_multi_exec("DELETE FROM config WHERE name = 'aux-clone-seqno';");
298 db_protect_pop();
299 }
300 db_end_transaction(0);
301 db_close(1);
302 db_open_repository(zRepo);
 
 
 
303 }
304 db_begin_transaction();
305 if( db_exists("SELECT 1 FROM delta WHERE srcId IN phantom") ){
306 fossil_warning("there are unresolved deltas -"
307 " the clone is probably incomplete and unusable.\n"
308 "It may be possible to resume the clone by running the"
309 " same command.");
 
 
 
 
310 }
311 fossil_print("Rebuilding repository meta-data...\n");
312 rebuild_db(1, 0);
313 if( !noCompress ){
314 int nDelta = 0;
315
--- src/clone.c
+++ src/clone.c
@@ -18,10 +18,11 @@
18 ** This file contains code used to clone a repository
19 */
20 #include "config.h"
21 #include "clone.h"
22 #include <assert.h>
23 #include <signal.h>
24
25 /*
26 ** If there are public BLOBs that deltas from private BLOBs, then
27 ** undeltify the public BLOBs so that the private BLOBs may be safely
28 ** deleted.
@@ -282,33 +283,46 @@
283 db_protect_pop();
284 url_enable_proxy(0);
285 clone_ssh_db_set_options();
286 url_get_password_if_needed();
287 g.xlinkClusterOnly = 1;
288 while( nResumes++<3 && sync_interrupted()==0
289 && (nErr = client_sync(syncFlags,CONFIGSET_ALL,0,0))
290 ){
291 if( sync_interrupted()!=0 ){
292 fossil_warning("cloning encountered errors, trying again.");
293 sqlite3_sleep(500);
294 }
295 }
296 g.xlinkClusterOnly = 0;
297 verify_cancel();
298 if( nErr ){
299 fossil_warning("server returned an error - clone incomplete");
300 }else if( sync_interrupted()==1 ){
301 fossil_warning("clone was interrupted");
302 }else{
303 db_unprotect(PROTECT_CONFIG);
304 db_multi_exec("DELETE FROM config WHERE name = 'aux-clone-seqno';");
305 db_protect_pop();
306 }
307 db_end_transaction(0);
308 db_close(1);
309 db_open_repository(zRepo);
310 #if !defined(_WIN32)
311 signal(SIGINT, SIG_DFL);
312 #endif
313 }
314 db_begin_transaction();
315 if( db_exists("SELECT 1 FROM delta WHERE srcId IN phantom") ){
316 if( db_get_int("aux-clone-seqno",0)==0 ){
317 fossil_fatal("there are unresolved deltas -"
318 " the clone is probabaly incomplete and unusable.");
319 }
320 }
321 if( db_get_int("aux-clone-seqno",0)>0 ){
322 fossil_warning("Clone incomplete - it may be possible to resume the"
323 " clone by running the same command again.");
324 }
325 fossil_print("Rebuilding repository meta-data...\n");
326 rebuild_db(1, 0);
327 if( !noCompress ){
328 int nDelta = 0;
329
+18
--- src/xfer.c
+++ src/xfer.c
@@ -1940,10 +1940,24 @@
19401940
** Floating-point absolute value
19411941
*/
19421942
static double fossil_fabs(double x){
19431943
return x>0.0 ? x : -x;
19441944
}
1945
+
1946
+/*
1947
+** Used during cloning to exit the sync loop prematurely
1948
+*/
1949
+static int bSyncGotIntr = 0;
1950
+static void sync_sigint_handler(int x){
1951
+ bSyncGotIntr = 1;
1952
+}
1953
+/*
1954
+** Interface to check whether sync was interrupted by SIGINT
1955
+*/
1956
+int sync_interrupted() {
1957
+ return bSyncGotIntr;
1958
+}
19451959
19461960
/*
19471961
** Sync to the host identified in g.url.name and g.url.path. This
19481962
** routine is called by the client.
19491963
**
@@ -2096,10 +2110,13 @@
20962110
*/
20972111
blob_appendf(&send, "pragma client-version %d %d %d\n",
20982112
RELEASE_VERSION_NUMBER, MANIFEST_NUMERIC_DATE,
20992113
MANIFEST_NUMERIC_TIME);
21002114
if( syncFlags & SYNC_CLONE ){
2115
+#if !defined(_WIN32)
2116
+ signal(SIGINT, sync_sigint_handler);
2117
+#endif
21012118
blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
21022119
syncFlags &= ~(SYNC_PUSH|SYNC_PULL);
21032120
nCardSent++;
21042121
/* TBD: Request all transferable configuration values */
21052122
content_enable_dephantomize(0);
@@ -2852,10 +2869,11 @@
28522869
/* Continue the clone until we see the clone_seqno 0" card or
28532870
** until we stop receiving artifacts */
28542871
go = 1;
28552872
}
28562873
}
2874
+ if( go && bSyncGotIntr ) go = 0;
28572875
28582876
nCardRcvd = 0;
28592877
xfer.nFileRcvd = 0;
28602878
xfer.nDeltaRcvd = 0;
28612879
xfer.nDanglingFile = 0;
28622880
--- src/xfer.c
+++ src/xfer.c
@@ -1940,10 +1940,24 @@
1940 ** Floating-point absolute value
1941 */
1942 static double fossil_fabs(double x){
1943 return x>0.0 ? x : -x;
1944 }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1945
1946 /*
1947 ** Sync to the host identified in g.url.name and g.url.path. This
1948 ** routine is called by the client.
1949 **
@@ -2096,10 +2110,13 @@
2096 */
2097 blob_appendf(&send, "pragma client-version %d %d %d\n",
2098 RELEASE_VERSION_NUMBER, MANIFEST_NUMERIC_DATE,
2099 MANIFEST_NUMERIC_TIME);
2100 if( syncFlags & SYNC_CLONE ){
 
 
 
2101 blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
2102 syncFlags &= ~(SYNC_PUSH|SYNC_PULL);
2103 nCardSent++;
2104 /* TBD: Request all transferable configuration values */
2105 content_enable_dephantomize(0);
@@ -2852,10 +2869,11 @@
2852 /* Continue the clone until we see the clone_seqno 0" card or
2853 ** until we stop receiving artifacts */
2854 go = 1;
2855 }
2856 }
 
2857
2858 nCardRcvd = 0;
2859 xfer.nFileRcvd = 0;
2860 xfer.nDeltaRcvd = 0;
2861 xfer.nDanglingFile = 0;
2862
--- src/xfer.c
+++ src/xfer.c
@@ -1940,10 +1940,24 @@
1940 ** Floating-point absolute value
1941 */
1942 static double fossil_fabs(double x){
1943 return x>0.0 ? x : -x;
1944 }
1945
1946 /*
1947 ** Used during cloning to exit the sync loop prematurely
1948 */
1949 static int bSyncGotIntr = 0;
1950 static void sync_sigint_handler(int x){
1951 bSyncGotIntr = 1;
1952 }
1953 /*
1954 ** Interface to check whether sync was interrupted by SIGINT
1955 */
1956 int sync_interrupted() {
1957 return bSyncGotIntr;
1958 }
1959
1960 /*
1961 ** Sync to the host identified in g.url.name and g.url.path. This
1962 ** routine is called by the client.
1963 **
@@ -2096,10 +2110,13 @@
2110 */
2111 blob_appendf(&send, "pragma client-version %d %d %d\n",
2112 RELEASE_VERSION_NUMBER, MANIFEST_NUMERIC_DATE,
2113 MANIFEST_NUMERIC_TIME);
2114 if( syncFlags & SYNC_CLONE ){
2115 #if !defined(_WIN32)
2116 signal(SIGINT, sync_sigint_handler);
2117 #endif
2118 blob_appendf(&send, "clone 3 %d\n", cloneSeqno);
2119 syncFlags &= ~(SYNC_PUSH|SYNC_PULL);
2120 nCardSent++;
2121 /* TBD: Request all transferable configuration values */
2122 content_enable_dephantomize(0);
@@ -2852,10 +2869,11 @@
2869 /* Continue the clone until we see the clone_seqno 0" card or
2870 ** until we stop receiving artifacts */
2871 go = 1;
2872 }
2873 }
2874 if( go && bSyncGotIntr ) go = 0;
2875
2876 nCardRcvd = 0;
2877 xfer.nFileRcvd = 0;
2878 xfer.nDeltaRcvd = 0;
2879 xfer.nDanglingFile = 0;
2880

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button