Cloud Backed SQLite

Check-in [60dc5b1d4a]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:Add the -httptimeout option to the daemon. For specifying a number of seconds after which to assume an HTTP request to cloud storage is lost. Default 600.
Downloads: Tarball | ZIP archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA3-256: 60dc5b1d4ab6e644e4ccdc92f45bc1090ed1249646b93f2abb1fb0732f0fcd11
User & Date: dan 2022-03-02 20:07:36.108
Context
2022-03-28
15:55
Add extra debugging logging for winsock errors. check-in: 59506d815f user: dan tags: trunk
15:26
Add extra debugging logging for winsock errors. check-in: 57a69119a7 user: dan tags: mistake
2022-03-16
16:27
Add the -httptimeout option to the daemon. For specifying a number of seconds after which to assume an HTTP request to cloud storage is lost. Default 600. check-in: 6e132fbfee user: dan tags: daemonless
2022-03-02
20:07
Add the -httptimeout option to the daemon. For specifying a number of seconds after which to assume an HTTP request to cloud storage is lost. Default 600. check-in: 60dc5b1d4a user: dan tags: trunk
2022-02-09
16:11
Add tests to ensure that the cloud storage system closing the socket connection unexpectedly is handled correctly. check-in: 0afede7e7d user: dan tags: trunk
Changes
Unified Diff Ignore Whitespace Patch
Changes to src/bcv_int.h.
185
186
187
188
189
190
191

192
193
194
195
196
197
198
};

int bcvDispatchNew(BcvDispatch**);
int bcvDispatchRun(BcvDispatch*, struct curl_waitfd *aFd, int nFd, int ms);
int bcvDispatchRunAll(BcvDispatch*);
void bcvDispatchFree(BcvDispatch*);
void bcvDispatchVerbose(BcvDispatch*, int);

void bcvDispatchLog(BcvDispatch*, void*, void (*xLog)(void*, const char*));

int bcvDispatchFetch(
  BcvDispatch *p,
  BcvContainer *pCont,
  const char *zFile,
  const char *zETag,







>







185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
};

int bcvDispatchNew(BcvDispatch**);
int bcvDispatchRun(BcvDispatch*, struct curl_waitfd *aFd, int nFd, int ms);
int bcvDispatchRunAll(BcvDispatch*);
void bcvDispatchFree(BcvDispatch*);
void bcvDispatchVerbose(BcvDispatch*, int);
void bcvDispatchTimeout(BcvDispatch*, int);
void bcvDispatchLog(BcvDispatch*, void*, void (*xLog)(void*, const char*));

int bcvDispatchFetch(
  BcvDispatch *p,
  BcvContainer *pCont,
  const char *zFile,
  const char *zETag,
Changes to src/bcvutil.c.
81
82
83
84
85
86
87

88
89
90
91
92
93
94
  int nData;
  int nAlloc;
};

struct BcvDispatch {
  CURLM *pMulti;                  /* The libcurl dispatcher ("multi-handle") */
  int bVerbose;                   /* True to make libcurl verbose */

  void *pLogApp;                  /* First argument to xLog() */
  void (*xLog)(void*, const char *zMsg);    /* Log function to invoke */
  int iNextRequestId;             /* Next request-id (for logging only) */
  BcvDispatchJob *pJobList;       /* List of current jobs */
};

struct sqlite3_bcv_job {







>







81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
  int nData;
  int nAlloc;
};

struct BcvDispatch {
  CURLM *pMulti;                  /* The libcurl dispatcher ("multi-handle") */
  int bVerbose;                   /* True to make libcurl verbose */
  int nHttpTimeout;
  void *pLogApp;                  /* First argument to xLog() */
  void (*xLog)(void*, const char *zMsg);    /* Log function to invoke */
  int iNextRequestId;             /* Next request-id (for logging only) */
  BcvDispatchJob *pJobList;       /* List of current jobs */
};

struct sqlite3_bcv_job {
2028
2029
2030
2031
2032
2033
2034




2035
2036
2037
2038
2039
2040
2041

  return rc;
}

void bcvDispatchVerbose(BcvDispatch *pDisp, int bVerbose){
  pDisp->bVerbose = bVerbose;
}





void bcvDispatchLog(
  BcvDispatch *pDisp,             /* Dispatcher object */
  void *pApp,                     /* First argument to pass to xLog() */
  void (*xLog)(void*, const char*)/* Function to invoke for http log messages */
){
  pDisp->xLog = xLog;







>
>
>
>







2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046

  return rc;
}

void bcvDispatchVerbose(BcvDispatch *pDisp, int bVerbose){
  pDisp->bVerbose = bVerbose;
}

void bcvDispatchTimeout(BcvDispatch *pDisp, int nHttpTimeout){
  pDisp->nHttpTimeout = nHttpTimeout;
}

void bcvDispatchLog(
  BcvDispatch *pDisp,             /* Dispatcher object */
  void *pApp,                     /* First argument to pass to xLog() */
  void (*xLog)(void*, const char*)/* Function to invoke for http log messages */
){
  pDisp->xLog = xLog;
2193
2194
2195
2196
2197
2198
2199

2200
2201
2202
2203
2204
2205
2206

    /* Invoke the log callback if one is configured */
    bcvDispatchLogRequest(p, pReq);

    curl_easy_setopt(pCurl, CURLOPT_PRIVATE, (void*)pReq);
    curl_easy_setopt(pCurl, CURLOPT_URL, pReq->zUri);
    curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pReq->pList);


    switch( pReq->eMethod ){
      case SQLITE_BCV_METHOD_GET:
        break;

      case SQLITE_BCV_METHOD_HEAD:
        curl_easy_setopt(pCurl, CURLOPT_NOBODY, (long)1);







>







2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212

    /* Invoke the log callback if one is configured */
    bcvDispatchLogRequest(p, pReq);

    curl_easy_setopt(pCurl, CURLOPT_PRIVATE, (void*)pReq);
    curl_easy_setopt(pCurl, CURLOPT_URL, pReq->zUri);
    curl_easy_setopt(pCurl, CURLOPT_HTTPHEADER, pReq->pList);
    curl_easy_setopt(pCurl, CURLOPT_TIMEOUT, (long)p->nHttpTimeout);

    switch( pReq->eMethod ){
      case SQLITE_BCV_METHOD_GET:
        break;

      case SQLITE_BCV_METHOD_HEAD:
        curl_easy_setopt(pCurl, CURLOPT_NOBODY, (long)1);
Changes to src/blockcachevfsd.c.
219
220
221
222
223
224
225

226
227
228
229
230
231
232
#define BCV_DEFAULT_CACHEFILE_SIZE   (1024*1024*1024)
#define BCV_DEFAULT_NWRITE           10
#define BCV_DEFAULT_NDELETE          10
#define BCV_DEFAULT_POLLTIME         10
#define BCV_DEFAULT_DELETETIME       3600
#define BCV_DEFAULT_GCTIME           3600
#define BCV_DEFAULT_RETRYTIME        10


/* Extra bytes reserved for nonce for each KiB of cache file */
#define BCV_LOCAL_NONCEPERKB      8

/*
** Size of nonce, in bytes, for pgsz byte pages.
*/







>







219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
#define BCV_DEFAULT_CACHEFILE_SIZE   (1024*1024*1024)
#define BCV_DEFAULT_NWRITE           10
#define BCV_DEFAULT_NDELETE          10
#define BCV_DEFAULT_POLLTIME         10
#define BCV_DEFAULT_DELETETIME       3600
#define BCV_DEFAULT_GCTIME           3600
#define BCV_DEFAULT_RETRYTIME        10
#define BCV_DEFAULT_HTTPTIMEOUT      600

/* Extra bytes reserved for nonce for each KiB of cache file */
#define BCV_LOCAL_NONCEPERKB      8

/*
** Size of nonce, in bytes, for pgsz byte pages.
*/
276
277
278
279
280
281
282

283
284
285
286
287
288
289
  int bPersistent;                /* Have the cache persist through restarts */
  int bVtab;                      /* True to enable bcv_* virtual-tables */
  int nWrite;                     /* Integer value of -nwrite option */
  int nDelete;                    /* Integer value of -deletes option */
  int bLazy;                      /* -lazy is present on command line */
  int bNononce;                   /* -nononce is present on command line */
  int nAutoDetach;                /* Value of -autodetach option */

};

#define BCV_LOG_MESSAGE  0x01
#define BCV_LOG_HTTP     0x20
#define BCV_LOG_EVENT    0x02
#define BCV_LOG_VERBOSE  0x40
#define BCV_LOG_SCHEDULE 0x80







>







277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
  int bPersistent;                /* Have the cache persist through restarts */
  int bVtab;                      /* True to enable bcv_* virtual-tables */
  int nWrite;                     /* Integer value of -nwrite option */
  int nDelete;                    /* Integer value of -deletes option */
  int bLazy;                      /* -lazy is present on command line */
  int bNononce;                   /* -nononce is present on command line */
  int nAutoDetach;                /* Value of -autodetach option */
  int nHttpTimeout;               /* Value of --httptimeout option */
};

#define BCV_LOG_MESSAGE  0x01
#define BCV_LOG_HTTP     0x20
#define BCV_LOG_EVENT    0x02
#define BCV_LOG_VERBOSE  0x40
#define BCV_LOG_SCHEDULE 0x80
528
529
530
531
532
533
534

535
536
537
538
539
540
541
#define COMMANDLINE_ALIAS        33
#define COMMANDLINE_POLL         34
#define COMMANDLINE_LAZY         35
#define COMMANDLINE_ADDR         36
#define COMMANDLINE_SECURE       37
#define COMMANDLINE_NONONCE      38
#define COMMANDLINE_AUTODETACH   39


#define COMMAND_ALL              0xFFFFFFFF
#define COMMAND_DAEMON           0x40000000
#define COMMAND_CREATE           0x20000000      /* -blocksize, -namebytes */
#define COMMAND_CMDLINE          0x08000000      /* -module, -user, -auth */
#define COMMAND_CONTAINER        0x04000000
#define COMMAND_NREQUEST         0x02000000      /* -nrequest */







>







530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
#define COMMANDLINE_ALIAS        33
#define COMMANDLINE_POLL         34
#define COMMANDLINE_LAZY         35
#define COMMANDLINE_ADDR         36
#define COMMANDLINE_SECURE       37
#define COMMANDLINE_NONONCE      38
#define COMMANDLINE_AUTODETACH   39
#define COMMANDLINE_HTTPTIMEOUT  40

#define COMMAND_ALL              0xFFFFFFFF
#define COMMAND_DAEMON           0x40000000
#define COMMAND_CREATE           0x20000000      /* -blocksize, -namebytes */
#define COMMAND_CMDLINE          0x08000000      /* -module, -user, -auth */
#define COMMAND_CONTAINER        0x04000000
#define COMMAND_NREQUEST         0x02000000      /* -nrequest */
563
564
565
566
567
568
569

570
571
572
573
574
575
576
    { "-port",           COMMAND_DAEMON         , COMMANDLINE_PORT         },
    { "-addr",           COMMAND_DAEMON         , COMMANDLINE_ADDR         },
    { "-cachesize",      COMMAND_DAEMON         , COMMANDLINE_CACHESIZE    },
    { "-autoexit",       COMMAND_DAEMON         , COMMANDLINE_AUTOEXIT     },
    { "-blocksize",      COMMAND_CREATE         , COMMANDLINE_BLOCKSIZE    },
    { "-polltime",       COMMAND_DAEMON         , COMMANDLINE_POLLTIME     },
    { "-deletetime",     COMMAND_DAEMON         , COMMANDLINE_DELETETIME   },

    { "-gctime",         COMMAND_DAEMON         , COMMANDLINE_GCTIME       },
    { "-retrytime",      COMMAND_DAEMON         , COMMANDLINE_RETRYTIME    },
    { "-log",            COMMAND_CMDLINE        , COMMANDLINE_LOG          },
    { "-nodelete",       COMMAND_DAEMON         , COMMANDLINE_NODELETE     },
    { "-nwrite",         COMMAND_DAEMON         , COMMANDLINE_NWRITE       },
    { "-ndelete",        COMMAND_DAEMON         , COMMANDLINE_NDELETE      },
    { "-readymessage",   COMMAND_DAEMON         , COMMANDLINE_READYMSG     },







>







566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
    { "-port",           COMMAND_DAEMON         , COMMANDLINE_PORT         },
    { "-addr",           COMMAND_DAEMON         , COMMANDLINE_ADDR         },
    { "-cachesize",      COMMAND_DAEMON         , COMMANDLINE_CACHESIZE    },
    { "-autoexit",       COMMAND_DAEMON         , COMMANDLINE_AUTOEXIT     },
    { "-blocksize",      COMMAND_CREATE         , COMMANDLINE_BLOCKSIZE    },
    { "-polltime",       COMMAND_DAEMON         , COMMANDLINE_POLLTIME     },
    { "-deletetime",     COMMAND_DAEMON         , COMMANDLINE_DELETETIME   },
    { "-httptimeout",    COMMAND_DAEMON         , COMMANDLINE_HTTPTIMEOUT  },
    { "-gctime",         COMMAND_DAEMON         , COMMANDLINE_GCTIME       },
    { "-retrytime",      COMMAND_DAEMON         , COMMANDLINE_RETRYTIME    },
    { "-log",            COMMAND_CMDLINE        , COMMANDLINE_LOG          },
    { "-nodelete",       COMMAND_DAEMON         , COMMANDLINE_NODELETE     },
    { "-nwrite",         COMMAND_DAEMON         , COMMANDLINE_NWRITE       },
    { "-ndelete",        COMMAND_DAEMON         , COMMANDLINE_NDELETE      },
    { "-readymessage",   COMMAND_DAEMON         , COMMANDLINE_READYMSG     },
611
612
613
614
615
616
617

618
619
620
621
622
623
624
      case COMMANDLINE_DIRECTORY:
      case COMMANDLINE_PORT:
      case COMMANDLINE_ADDR:
      case COMMANDLINE_CACHESIZE:
      case COMMANDLINE_BLOCKSIZE:
      case COMMANDLINE_POLLTIME:
      case COMMANDLINE_DELETETIME:

      case COMMANDLINE_GCTIME:
      case COMMANDLINE_RETRYTIME:
      case COMMANDLINE_LOG:
      case COMMANDLINE_NWRITE:
      case COMMANDLINE_NDELETE:
      case COMMANDLINE_NAMEBYTES:
      case COMMANDLINE_MODULE:







>







615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
      case COMMANDLINE_DIRECTORY:
      case COMMANDLINE_PORT:
      case COMMANDLINE_ADDR:
      case COMMANDLINE_CACHESIZE:
      case COMMANDLINE_BLOCKSIZE:
      case COMMANDLINE_POLLTIME:
      case COMMANDLINE_DELETETIME:
      case COMMANDLINE_HTTPTIMEOUT:
      case COMMANDLINE_GCTIME:
      case COMMANDLINE_RETRYTIME:
      case COMMANDLINE_LOG:
      case COMMANDLINE_NWRITE:
      case COMMANDLINE_NDELETE:
      case COMMANDLINE_NAMEBYTES:
      case COMMANDLINE_MODULE:
732
733
734
735
736
737
738



739
740
741
742
743
744
745
        break;
      case COMMANDLINE_POLLTIME:
        pCmd->nPollTime = parse_seconds(azArg[i]);
        break;
      case COMMANDLINE_DELETETIME:
        pCmd->nDeleteTime = parse_seconds(azArg[i]);
        break;



      case COMMANDLINE_GCTIME:
        pCmd->nGCTime = parse_seconds(azArg[i]);
        break;
      case COMMANDLINE_RETRYTIME:
        pCmd->nRetryTime = parse_seconds(azArg[i]);
        break;
      case COMMANDLINE_AUTODETACH:







>
>
>







737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
        break;
      case COMMANDLINE_POLLTIME:
        pCmd->nPollTime = parse_seconds(azArg[i]);
        break;
      case COMMANDLINE_DELETETIME:
        pCmd->nDeleteTime = parse_seconds(azArg[i]);
        break;
      case COMMANDLINE_HTTPTIMEOUT:
        pCmd->nHttpTimeout = parse_seconds(azArg[i]);
        break;
      case COMMANDLINE_GCTIME:
        pCmd->nGCTime = parse_seconds(azArg[i]);
        break;
      case COMMANDLINE_RETRYTIME:
        pCmd->nRetryTime = parse_seconds(azArg[i]);
        break;
      case COMMANDLINE_AUTODETACH:
6213
6214
6215
6216
6217
6218
6219

6220
6221
6222
6223
6224
6225
6226

  if( pCmd->nWrite<=0 ) pCmd->nWrite = BCV_DEFAULT_NWRITE;
  if( pCmd->nDelete<=0 ) pCmd->nDelete = BCV_DEFAULT_NDELETE;
  if( pCmd->nPollTime<=0 ) pCmd->nPollTime = BCV_DEFAULT_POLLTIME;
  if( pCmd->nDeleteTime<=0 ) pCmd->nDeleteTime = BCV_DEFAULT_DELETETIME;
  if( pCmd->nGCTime<=0 ) pCmd->nGCTime = BCV_DEFAULT_GCTIME;
  if( pCmd->nRetryTime<=0 ) pCmd->nRetryTime = BCV_DEFAULT_RETRYTIME;


  if( iCont<nArg && pCmd->zSecret==0 ){
    fatal_error("Specifying containers on command line requires -auth");
  }

  /* Open the listen socket */
  bdListen(p);







>







6221
6222
6223
6224
6225
6226
6227
6228
6229
6230
6231
6232
6233
6234
6235

  if( pCmd->nWrite<=0 ) pCmd->nWrite = BCV_DEFAULT_NWRITE;
  if( pCmd->nDelete<=0 ) pCmd->nDelete = BCV_DEFAULT_NDELETE;
  if( pCmd->nPollTime<=0 ) pCmd->nPollTime = BCV_DEFAULT_POLLTIME;
  if( pCmd->nDeleteTime<=0 ) pCmd->nDeleteTime = BCV_DEFAULT_DELETETIME;
  if( pCmd->nGCTime<=0 ) pCmd->nGCTime = BCV_DEFAULT_GCTIME;
  if( pCmd->nRetryTime<=0 ) pCmd->nRetryTime = BCV_DEFAULT_RETRYTIME;
  if( pCmd->nHttpTimeout<=0 ) pCmd->nHttpTimeout = BCV_DEFAULT_HTTPTIMEOUT;

  if( iCont<nArg && pCmd->zSecret==0 ){
    fatal_error("Specifying containers on command line requires -auth");
  }

  /* Open the listen socket */
  bdListen(p);
6253
6254
6255
6256
6257
6258
6259

6260
6261
6262
6263
6264
6265
6266
  bdCheckNononce(p);
  bdWritePortNumber(p);

  /* Allocate a dispatcher object for the daemon to use */
  rc = bcvDispatchNew(&p->pDisp);
  if( rc!=SQLITE_OK ) fatal_oom_error();
  bcvDispatchVerbose(p->pDisp, (pCmd->mLog & BCV_LOG_VERBOSE) ? 1 : 0);

  if( pCmd->mLog & BCV_LOG_HTTP ){
    bcvDispatchLog(p->pDisp, p, bdHttpLog);
  }

  bdContainerIter(p, nArg-iCont, (const char**)&azArg[iCont], &pIter);
  while( SQLITE_ROW==sqlite3_step(pIter) ){
    const char *zCont = (const char*)sqlite3_column_text(pIter, 0);







>







6262
6263
6264
6265
6266
6267
6268
6269
6270
6271
6272
6273
6274
6275
6276
  bdCheckNononce(p);
  bdWritePortNumber(p);

  /* Allocate a dispatcher object for the daemon to use */
  rc = bcvDispatchNew(&p->pDisp);
  if( rc!=SQLITE_OK ) fatal_oom_error();
  bcvDispatchVerbose(p->pDisp, (pCmd->mLog & BCV_LOG_VERBOSE) ? 1 : 0);
  bcvDispatchTimeout(p->pDisp, pCmd->nHttpTimeout);
  if( pCmd->mLog & BCV_LOG_HTTP ){
    bcvDispatchLog(p->pDisp, p, bdHttpLog);
  }

  bdContainerIter(p, nArg-iCont, (const char**)&azArg[iCont], &pIter);
  while( SQLITE_ROW==sqlite3_step(pIter) ){
    const char *zCont = (const char*)sqlite3_column_text(pIter, 0);
Added test/bcv_proxy_hang2.test.












































































































>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#
# 26-July-2021
#
#-------------------------------------------------------------------------
#

source [file join [file dirname [info script]] test_common.tcl]
set testprefix bcv_proxy_hang2

# This test is designed to run with the proxy.tcl/azurite combination 
# only. Print an error message and exit if it cannot be found.
if {[catch bcv_proxy_test msg]} { puts $msg ; exit }


# Configure the proxy to pass everything straight through.
#
bcv_proxy_config {
  DELETE FROM new_client_message;
}

# Initialize a new system
start_new_system -poll 1 -httptimeout 5

# Write to one of the databases. Upload it.
bcv_sqlite3 db test.db1
do_execsql_test 1.0 {
  CREATE TABLE x1(a INTEGER PRIMARY KEY, b TEXT);
  PRAGMA bcv_upload;
} {ok}

bcv_proxy_config {
  INSERT INTO new_client_message(pattern, action) VALUES
    ('GET%', 'delay 84600000');
}

wait_ms 5000

bcv_proxy_config {
  DELETE FROM new_client_message
}

do_test 1.1 {
  list [catch { bcv_attach -poll $::D(container) } msg] $msg
} {1 {failed to load manifest for bcvtest5: Timeout was reached}}

do_test 1.2 {
  list [catch { bcv_attach -poll $::D(container) } msg] $msg
} {0 {}}

db close
wait_daemon 0

finish_test

Changes to test/test_common.tcl.
87
88
89
90
91
92
93

94
95
96
97
98
99
100
set D(blocksize) 131072
set D(cachesize)  1G
set D(polltime)   2
set D(nwrite)     10
set D(deletetime) 2
set D(retrytime)  10
set D(gctime)     3600


proc make_container_name {name} {
  global C
  if {[info exists C(postfix)]} {
    append name $C(postfix)
  }
  return $name







>







87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
set D(blocksize) 131072
set D(cachesize)  1G
set D(polltime)   2
set D(nwrite)     10
set D(deletetime) 2
set D(retrytime)  10
set D(gctime)     3600
set D(httptimeout) 600

proc make_container_name {name} {
  global C
  if {[info exists C(postfix)]} {
    append name $C(postfix)
  }
  return $name
606
607
608
609
610
611
612

613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
  {-deletetime $D(deletetime)}
  {-retrytime $D(retrytime)}
  {-gctime $D(gctime)}
  {-module $C(module)}
  {-authentication {$C(auth)}}
  {-user $C(user)}
  {-autodetach 0}

" {
  array get O
}

proc extract_args {lArg lBool} {
  upvar O O
  set ret [list]
  foreach b $lBool {
    if {$O($b)} { lappend ret $b }
  }
  foreach a $lArg {
    lappend ret $a $O($a)
  }
  set ret
}

proc daemon_args {} {
  upvar O O
  lappend a -log -cachesize -polltime -nwrite -deletetime -gctime -user
  lappend a -module -authentication -autodetach
  set b {-persistent -vtab -nodelete -lazy -nononce}
  extract_args $a $b
}

proc daemon_args_debug {} {
  upvar O O
  concat [daemon_args] [extract_args {} {-debug -valgrind -noattach}]







>



















|







607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
  {-deletetime $D(deletetime)}
  {-retrytime $D(retrytime)}
  {-gctime $D(gctime)}
  {-module $C(module)}
  {-authentication {$C(auth)}}
  {-user $C(user)}
  {-autodetach 0}
  {-httptimeout $D(httptimeout)}
" {
  array get O
}

proc extract_args {lArg lBool} {
  upvar O O
  set ret [list]
  foreach b $lBool {
    if {$O($b)} { lappend ret $b }
  }
  foreach a $lArg {
    lappend ret $a $O($a)
  }
  set ret
}

proc daemon_args {} {
  upvar O O
  lappend a -log -cachesize -polltime -nwrite -deletetime -gctime -user
  lappend a -httptimeout -module -authentication -autodetach
  set b {-persistent -vtab -nodelete -lazy -nononce}
  extract_args $a $b
}

proc daemon_args_debug {} {
  upvar O O
  concat [daemon_args] [extract_args {} {-debug -valgrind -noattach}]