Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
V
varnish-cache
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Commits
Open sidebar
varnishcache
varnish-cache
Commits
e4d1d360
Commit
e4d1d360
authored
Nov 20, 2011
by
Poul-Henning Kamp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Polish round over varnishd part of VSM
parent
356d46a8
Changes
15
Show whitespace changes
Inline
Side-by-side
Showing
15 changed files
with
225 additions
and
264 deletions
+225
-264
cache_shmlog.c
bin/varnishd/cache/cache_shmlog.c
+0
-2
common.h
bin/varnishd/common/common.h
+3
-22
common_vsm.c
bin/varnishd/common/common_vsm.c
+27
-35
params.h
bin/varnishd/common/params.h
+2
-0
mgt.h
bin/varnishd/mgt/mgt.h
+0
-1
mgt_cli.c
bin/varnishd/mgt/mgt_cli.c
+5
-5
mgt_main.c
bin/varnishd/mgt/mgt_main.c
+0
-2
mgt_pool.c
bin/varnishd/mgt/mgt_pool.c
+0
-1
mgt_sandbox.c
bin/varnishd/mgt/mgt_sandbox.c
+0
-1
mgt_shmem.c
bin/varnishd/mgt/mgt_shmem.c
+86
-101
vsm.h
include/vapi/vsm.h
+10
-1
vsm_int.h
include/vapi/vsm_int.h
+66
-62
vsl.c
lib/libvarnishapi/vsl.c
+2
-1
vsm.c
lib/libvarnishapi/vsm.c
+23
-28
vsm_api.h
lib/libvarnishapi/vsm_api.h
+1
-2
No files found.
bin/varnishd/cache/cache_shmlog.c
View file @
e4d1d360
...
...
@@ -37,9 +37,7 @@
#include "cache_backend.h" // For w->vbc
#include "vapi/vsm_int.h"
#include "vmb.h"
#include "vtim.h"
/* These cannot be struct lock, which depends on vsm/vsl working */
static
pthread_mutex_t
vsl_mtx
;
...
...
bin/varnishd/common/common.h
View file @
e4d1d360
...
...
@@ -75,30 +75,11 @@ void mgt_child_inherit(int fd, const char *what);
/* vsm.c */
struct
vsm_sc
;
struct
vsm_sc
*
VSM_common_new
(
void
*
ptr
,
unsigned
len
);
void
*
VSM_common_alloc
(
struct
vsm_sc
*
sc
,
unsigned
size
,
struct
vsm_sc
*
VSM_common_new
(
void
*
ptr
,
ssize_t
len
);
void
*
VSM_common_alloc
(
struct
vsm_sc
*
sc
,
ssize_t
size
,
const
char
*
class
,
const
char
*
type
,
const
char
*
ident
);
void
VSM_common_free
(
struct
vsm_sc
*
sc
,
void
*
ptr
);
void
VSM_common_delete
(
struct
vsm_sc
*
sc
);
// extern struct VSM_head *VSM_head;
// extern const struct VSM_chunk *vsm_end;
/*
* These three should not be called directly, but only through
* proper vectors in mgt.h/cache.h, hence the __
*/
void
*
VSM__Alloc
(
unsigned
size
,
const
char
*
class
,
const
char
*
type
,
const
char
*
ident
);
void
VSM__Free
(
const
void
*
ptr
);
void
VSM__Clean
(
void
);
/* These classes are opaque to other programs, so we define the here */
#define VSM_CLASS_FREE "Free"
#define VSM_CLASS_COOL "Cool"
#define VSM_CLASS_PARAM "Params"
#define VSM_CLASS_MARK "MgrCld"
#define VSM_COOL_TIME 5
void
VSM_common_delete
(
struct
vsm_sc
**
sc
);
/*---------------------------------------------------------------------
* Generic power-2 rounding macros
...
...
bin/varnishd/common/common_vsm.c
View file @
e4d1d360
...
...
@@ -27,27 +27,8 @@
*
* VSM stuff common to manager and child.
*
* We have three potential conflicts we need to deal with:
*
* VSM-studying programs (varnishstat...) vs. everybody else
* The VSM studying programs only have read-only access to the VSM
* so everybody else must use memory barriers, stable storage and
* similar tricks to keep the VSM image in sync (long enough) for
* the studying programs.
* It can not be prevented, and may indeed in some cases be
* desirable for such programs to write to VSM, for instance to
* zero counters.
* Varnishd should never trust the integrity of VSM content.
*
* Manager process vs child process.
* The manager will create a fresh VSM for each child process launch
* and not muck about with VSM while the child runs. If the child
* crashes, the panicstring will be evacuated and the VSM possibly
* saved for debugging, and a new VSM created before the child is
* started again.
*
* Child process threads
* Pthread locking necessary.
* Please see comments in <vapi/vsm_int.h> for details of protocols and
* data consistency.
*
*/
...
...
@@ -71,8 +52,8 @@ struct vsm_range {
unsigned
magic
;
#define VSM_RANGE_MAGIC 0x8d30f14
VTAILQ_ENTRY
(
vsm_range
)
list
;
unsigned
off
;
unsigned
len
;
ssize_t
off
;
ssize_t
len
;
double
cool
;
struct
VSM_chunk
*
chunk
;
void
*
ptr
;
...
...
@@ -82,7 +63,7 @@ struct vsm_sc {
unsigned
magic
;
#define VSM_SC_MAGIC 0x8b83270d
char
*
b
;
unsigned
len
;
ssize_t
len
;
struct
VSM_head
*
head
;
VTAILQ_HEAD
(,
vsm_range
)
r_used
;
VTAILQ_HEAD
(,
vsm_range
)
r_cooling
;
...
...
@@ -137,7 +118,7 @@ vsm_common_insert_free(struct vsm_sc *sc, struct vsm_range *vr)
*/
struct
vsm_sc
*
VSM_common_new
(
void
*
p
,
unsigned
l
)
VSM_common_new
(
void
*
p
,
ssize_t
l
)
{
struct
vsm_sc
*
sc
;
struct
vsm_range
*
vr
;
...
...
@@ -154,10 +135,13 @@ VSM_common_new(void *p, unsigned l)
sc
->
len
=
l
;
sc
->
head
=
(
void
*
)
sc
->
b
;
memset
(
TRUST_ME
(
sc
->
head
),
0
,
sizeof
*
sc
->
head
);
/* This should not be necessary, but just in case...*/
memset
(
sc
->
head
,
0
,
sizeof
*
sc
->
head
);
sc
->
head
->
magic
=
VSM_HEAD_MAGIC
;
sc
->
head
->
hdrsize
=
sizeof
*
sc
->
head
;
sc
->
head
->
shm_size
=
l
;
sc
->
head
->
alloc_seq
=
random
()
|
1
;
VWMB
();
ALLOC_OBJ
(
vr
,
VSM_RANGE_MAGIC
);
AN
(
vr
);
...
...
@@ -172,7 +156,7 @@ VSM_common_new(void *p, unsigned l)
*/
void
*
VSM_common_alloc
(
struct
vsm_sc
*
sc
,
unsigned
size
,
VSM_common_alloc
(
struct
vsm_sc
*
sc
,
ssize_t
size
,
const
char
*
class
,
const
char
*
type
,
const
char
*
ident
)
{
struct
vsm_range
*
vr
,
*
vr2
,
*
vr3
;
...
...
@@ -238,15 +222,15 @@ VSM_common_alloc(struct vsm_sc *sc, unsigned size,
/* XXX: stats ? */
/* Zero the entire allocation, to avoid garbage confusing readers */
memset
(
TRUST_ME
(
sc
->
b
+
vr
->
off
)
,
0
,
vr
->
len
);
memset
(
sc
->
b
+
vr
->
off
,
0
,
vr
->
len
);
vr
->
chunk
=
(
void
*
)(
sc
->
b
+
vr
->
off
);
vr
->
ptr
=
(
vr
->
chunk
+
1
);
vr
->
chunk
->
magic
=
VSM_CHUNK_MAGIC
;
strcpy
(
TRUST_ME
(
vr
->
chunk
->
class
)
,
class
);
strcpy
(
TRUST_ME
(
vr
->
chunk
->
type
)
,
type
);
strcpy
(
TRUST_ME
(
vr
->
chunk
->
ident
)
,
ident
);
strcpy
(
vr
->
chunk
->
class
,
class
);
strcpy
(
vr
->
chunk
->
type
,
type
);
strcpy
(
vr
->
chunk
->
ident
,
ident
);
VWMB
();
vr3
=
VTAILQ_FIRST
(
&
sc
->
r_used
);
...
...
@@ -258,6 +242,7 @@ VSM_common_alloc(struct vsm_sc *sc, unsigned size,
}
else
{
sc
->
head
->
first
=
vr
->
off
;
}
sc
->
head
->
alloc_seq
+=
2
;
VWMB
();
return
(
vr
->
ptr
);
}
...
...
@@ -289,6 +274,7 @@ VSM_common_free(struct vsm_sc *sc, void *ptr)
sc
->
head
->
first
=
vr
->
chunk
->
next
;
VWMB
();
vr
->
chunk
->
len
=
0
;
sc
->
head
->
alloc_seq
+=
2
;
VWMB
();
return
;
}
...
...
@@ -298,7 +284,7 @@ VSM_common_free(struct vsm_sc *sc, void *ptr)
VTAILQ_REMOVE
(
&
sc
->
r_bogus
,
vr
,
list
);
FREE_OBJ
(
vr
);
/* XXX: stats ? */
free
(
TRUST_ME
(
ptr
)
);
free
(
ptr
);
return
;
}
}
...
...
@@ -311,9 +297,14 @@ VSM_common_free(struct vsm_sc *sc, void *ptr)
*/
void
VSM_common_delete
(
struct
vsm_sc
*
sc
)
VSM_common_delete
(
struct
vsm_sc
*
*
scp
)
{
struct
vsm_range
*
vr
,
*
vr2
;
struct
vsm_sc
*
sc
;
AN
(
scp
);
sc
=*
scp
;
*
scp
=
NULL
;
CHECK_OBJ_NOTNULL
(
sc
,
VSM_SC_MAGIC
);
VTAILQ_FOREACH_SAFE
(
vr
,
&
sc
->
r_free
,
list
,
vr2
)
...
...
@@ -323,9 +314,10 @@ VSM_common_delete(struct vsm_sc *sc)
VTAILQ_FOREACH_SAFE
(
vr
,
&
sc
->
r_cooling
,
list
,
vr2
)
FREE_OBJ
(
vr
);
VTAILQ_FOREACH_SAFE
(
vr
,
&
sc
->
r_bogus
,
list
,
vr2
)
{
free
(
TRUST_ME
(
vr
->
ptr
)
);
free
(
vr
->
ptr
);
FREE_OBJ
(
vr
);
}
sc
->
head
->
magic
=
0
;
sc
->
head
->
alloc_seq
=
0
;
VWMB
();
FREE_OBJ
(
sc
);
}
bin/varnishd/common/params.h
View file @
e4d1d360
...
...
@@ -31,6 +31,8 @@
#include "vre.h"
#define VSM_CLASS_PARAM "Params"
struct
params
{
/* Unprivileged user / group */
...
...
bin/varnishd/mgt/mgt.h
View file @
e4d1d360
...
...
@@ -82,7 +82,6 @@ void mgt_sandbox_solaris_privsep(void);
/* mgt_shmem.c */
void
mgt_SHM_Init
(
void
);
void
mgt_SHM_Pid
(
void
);
/* stevedore_mgt.c */
void
STV_Config
(
const
char
*
spec
);
...
...
bin/varnishd/mgt/mgt_cli.c
View file @
e4d1d360
...
...
@@ -493,13 +493,13 @@ mgt_cli_secret(const char *S_arg)
{
int
i
,
fd
;
char
buf
[
BUFSIZ
];
volatile
char
*
p
;
char
*
p
;
/* Save in shmem */
i
=
strlen
(
S_arg
);
p
=
VSM_Alloc
(
i
+
1
,
"Arg"
,
"-S"
,
""
);
p
=
VSM_Alloc
(
i
+
1
L
,
"Arg"
,
"-S"
,
""
);
AN
(
p
);
memcpy
(
TRUST_ME
(
p
),
S_arg
,
i
+
1
);
memcpy
(
p
,
S_arg
,
i
+
1L
);
srandomdev
();
/* XXX: why here ??? */
fd
=
open
(
S_arg
,
O_RDONLY
);
...
...
@@ -527,7 +527,7 @@ mgt_cli_telnet(const char *T_arg)
struct
vss_addr
**
ta
;
int
i
,
n
,
sock
,
good
;
struct
telnet
*
tn
;
volatile
char
*
p
;
char
*
p
;
struct
vsb
*
vsb
;
char
abuf
[
VTCP_ADDRBUFSIZE
];
char
pbuf
[
VTCP_PORTBUFSIZE
];
...
...
@@ -566,7 +566,7 @@ mgt_cli_telnet(const char *T_arg)
/* Save in shmem */
p
=
VSM_Alloc
(
VSB_len
(
vsb
)
+
1
,
"Arg"
,
"-T"
,
""
);
AN
(
p
);
memcpy
(
TRUST_ME
(
p
)
,
VSB_data
(
vsb
),
VSB_len
(
vsb
)
+
1
);
memcpy
(
p
,
VSB_data
(
vsb
),
VSB_len
(
vsb
)
+
1
);
VSB_delete
(
vsb
);
}
...
...
bin/varnishd/mgt/mgt_main.c
View file @
e4d1d360
...
...
@@ -630,8 +630,6 @@ main(int argc, char * const *argv)
if
(
!
d_flag
&&
!
F_flag
)
AZ
(
varnish_daemon
(
1
,
0
));
mgt_SHM_Pid
();
if
(
pfh
!=
NULL
&&
VPF_Write
(
pfh
))
fprintf
(
stderr
,
"NOTE: Could not write PID file
\n
"
);
...
...
bin/varnishd/mgt/mgt_pool.c
View file @
e4d1d360
...
...
@@ -48,7 +48,6 @@
#include <unistd.h>
#include "mgt/mgt.h"
#include "common/heritage.h"
#include "common/params.h"
#include "mgt/mgt_param.h"
...
...
bin/varnishd/mgt/mgt_sandbox.c
View file @
e4d1d360
...
...
@@ -53,7 +53,6 @@
#include <unistd.h>
#include "mgt/mgt.h"
#include "common/heritage.h"
#include "common/params.h"
/*--------------------------------------------------------------------*/
...
...
bin/varnishd/mgt/mgt_shmem.c
View file @
e4d1d360
...
...
@@ -90,7 +90,6 @@
#include <sys/stat.h>
#include <fcntl.h>
#include <signal.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
...
...
@@ -103,7 +102,6 @@
#include "flopen.h"
#include "vapi/vsc_int.h"
#include "vapi/vsl_int.h"
#include "vapi/vsm_int.h"
#include "vmb.h"
...
...
@@ -117,88 +115,96 @@
struct
VSC_C_main
*
VSC_C_main
;
static
int
vs
l
_fd
=
-
1
;
static
int
vs
m
_fd
=
-
1
;
/*--------------------------------------------------------------------
* Check that we are not started with the same -n argument as an already
* running varnishd
* running varnishd.
*
* Non-zero return means we should exit and not trample the file.
*
*/
static
void
vs
l_n_check
(
int
f
d
)
static
int
vs
m_n_check
(
voi
d
)
{
struct
VSM_head
slh
;
int
i
;
int
fd
,
i
;
struct
stat
st
;
pid_t
pid
;
struct
VSM_head
vsmh
;
int
retval
=
2
;
AZ
(
fstat
(
fd
,
&
st
)
);
if
(
!
S_ISREG
(
st
.
st_mode
)
)
ARGV_ERR
(
"
\t
shmlog: Not a file
\n
"
);
fd
=
open
(
VSM_FILENAME
,
O_RDWR
,
0644
);
if
(
fd
<
0
)
return
(
0
);
/* Test if the SHMFILE is locked by other Varnish */
if
(
fltest
(
fd
,
&
pid
)
>
0
)
{
AZ
(
fstat
(
fd
,
&
st
));
if
(
!
S_ISREG
(
st
.
st_mode
)
)
{
fprintf
(
stderr
,
"SHMFILE locked by running varnishd master (pid=%jd)
\n
"
,
(
intmax_t
)
pid
);
"VSM (%s) not a regular file.
\n
"
,
VSM_FILENAME
);
}
else
{
i
=
fltest
(
fd
,
&
pid
);
if
(
i
<
0
)
{
fprintf
(
stderr
,
"(Use unique -n arguments if you want multiple "
"instances)
\n
"
);
exit
(
2
);
"Cannot determine locking status of VSM (%s)
\n
."
,
VSM_FILENAME
);
}
else
if
(
i
==
0
)
{
/*
* File is unlocked, mark it as dead, to help any
* consumers still stuck on it.
*/
if
(
pread
(
fd
,
&
vsmh
,
sizeof
vsmh
,
0
)
==
sizeof
vsmh
)
{
vsmh
.
alloc_seq
=
0
;
(
void
)
pwrite
(
fd
,
&
vsmh
,
sizeof
vsmh
,
0
);
}
/* Read owning pid from SHMFILE */
memset
(
&
slh
,
0
,
sizeof
slh
);
/* XXX: for flexelint */
i
=
read
(
fd
,
&
slh
,
sizeof
slh
);
if
(
i
!=
sizeof
slh
)
return
;
if
(
slh
.
magic
!=
VSM_HEAD_MAGIC
)
return
;
if
(
slh
.
hdrsize
!=
sizeof
slh
)
return
;
if
(
slh
.
master_pid
!=
0
&&
!
kill
(
slh
.
master_pid
,
0
))
{
retval
=
0
;
}
else
{
/* The VSM is locked, we won't touch it. */
fprintf
(
stderr
,
"WARNING: Taking over SHMFILE marked as owned by "
"running process (pid=%jd)
\n
"
,
(
intmax_t
)
slh
.
master_pid
);
"VSM locked by running varnishd master (pid=%jd)
\n
"
"(Use unique -n arguments if you want"
" multiple instances)
\n
"
,
(
intmax_t
)
pid
);
}
}
(
void
)
close
(
fd
);
return
(
retval
);
}
/*--------------------------------------------------------------------
* Build a
new shmlog
file
* Build a
zeroed
file
*/
static
void
vs
l_buildnew
(
const
char
*
fn
,
ssize_t
size
)
static
int
vs
m_zerofile
(
const
char
*
fn
,
ssize_t
size
)
{
int
i
;
unsigned
u
;
int
fd
;
ssize_t
i
,
u
;
char
buf
[
64
*
1024
];
int
flags
;
(
void
)
unlink
(
fn
);
vsl_fd
=
flopen
(
fn
,
O_RDWR
|
O_CREAT
|
O_EXCL
|
O_NONBLOCK
,
0644
);
if
(
vsl_fd
<
0
)
{
fd
=
flopen
(
fn
,
O_RDWR
|
O_CREAT
|
O_EXCL
|
O_NONBLOCK
,
0644
);
if
(
fd
<
0
)
{
fprintf
(
stderr
,
"Could not create %s: %s
\n
"
,
fn
,
strerror
(
errno
));
exit
(
1
);
return
(
-
1
);
}
flags
=
fcntl
(
vsl_
fd
,
F_GETFL
);
flags
=
fcntl
(
fd
,
F_GETFL
);
assert
(
flags
!=
-
1
);
flags
&=
~
O_NONBLOCK
;
AZ
(
fcntl
(
vsl_
fd
,
F_SETFL
,
flags
));
AZ
(
fcntl
(
fd
,
F_SETFL
,
flags
));
memset
(
buf
,
0
,
sizeof
buf
);
for
(
u
=
0
;
u
<
size
;
)
{
i
=
write
(
vsl_
fd
,
buf
,
sizeof
buf
);
i
=
write
(
fd
,
buf
,
sizeof
buf
);
if
(
i
<=
0
)
{
fprintf
(
stderr
,
"Write error %s: %s
\n
"
,
fn
,
strerror
(
errno
));
exit
(
1
);
return
(
-
1
);
}
u
+=
i
;
}
AZ
(
ftruncate
(
vsl_fd
,
(
off_t
)
size
));
AZ
(
ftruncate
(
fd
,
(
off_t
)
size
));
return
(
fd
);
}
/*--------------------------------------------------------------------
...
...
@@ -209,48 +215,59 @@ static
void
mgt_shm_atexit
(
void
)
{
#if 0
if (getpid() == VSM_head->master_pid)
VSM_head->master_pid = 0;
#endif
if
(
heritage
.
vsm
!=
NULL
)
VSM_common_delete
(
&
heritage
.
vsm
);
}
void
mgt_SHM_Init
(
void
)
{
int
i
,
fill
;
int
i
;
uintmax_t
size
,
ps
;
void
*
p
;
#if 0
uint32_t *vsl_log_start;
#endif
fill
=
1
;
char
fnbuf
[
64
];
size
=
mgt_param
.
vsl_space
+
mgt_param
.
vsm_space
;
ps
=
getpagesize
();
size
+=
ps
-
1
;
size
&=
~
(
ps
-
1
);
i
=
open
(
VSM_FILENAME
,
O_RDWR
,
0644
);
if
(
i
>=
0
)
{
vsl_n_check
(
i
);
(
void
)
close
(
i
);
}
vsl_buildnew
(
VSM_FILENAME
,
size
);
/* Collision check with already running varnishd */
i
=
vsm_n_check
();
if
(
i
)
exit
(
i
);
bprintf
(
fnbuf
,
"%s.%jd"
,
VSM_FILENAME
,
(
intmax_t
)
getpid
());
vsm_fd
=
vsm_zerofile
(
fnbuf
,
size
);
if
(
vsm_fd
<
0
)
exit
(
1
);
p
=
(
void
*
)
mmap
(
NULL
,
size
,
PROT_READ
|
PROT_WRITE
,
MAP_HASSEMAPHORE
|
MAP_NOSYNC
|
MAP_SHARED
,
vsl_fd
,
0
);
xxxassert
(
p
!=
MAP_FAILED
);
vsm_fd
,
0
);
heritage
.
vsm
=
VSM_common_new
(
p
,
size
);
if
(
p
==
MAP_FAILED
)
{
fprintf
(
stderr
,
"Mmap error %s: %s
\n
"
,
fnbuf
,
strerror
(
errno
));
exit
(
-
1
);
}
/* This may or may not work */
(
void
)
mlock
(
p
,
size
);
heritage
.
vsm
=
VSM_common_new
(
p
,
size
);
if
(
rename
(
fnbuf
,
VSM_FILENAME
))
{
fprintf
(
stderr
,
"Rename failed %s -> %s: %s
\n
"
,
fnbuf
,
VSM_FILENAME
,
strerror
(
errno
));
(
void
)
unlink
(
fnbuf
);
exit
(
-
1
);
}
AZ
(
atexit
(
mgt_shm_atexit
));
/* XXX: We need to zero params if we dealloc/clean/wash */
cache_param
=
VSM_Alloc
(
sizeof
*
cache_param
,
VSM_CLASS_PARAM
,
""
,
""
);
AN
(
cache_param
);
*
cache_param
=
mgt_param
;
...
...
@@ -258,36 +275,4 @@ mgt_SHM_Init(void)
PAN_panicstr_len
=
64
*
1024
;
PAN_panicstr
=
VSM_Alloc
(
PAN_panicstr_len
,
PAN_CLASS
,
""
,
""
);
AN
(
PAN_panicstr
);
#if 0
VSM_head->master_pid = getpid();
memset(&VSM_head->head, 0, sizeof VSM_head->head);
VSM_head->head.magic = VSM_CHUNK_MAGIC;
VSM_head->head.len =
(uint8_t*)(VSM_head) + size - (uint8_t*)&VSM_head->head;
bprintf(VSM_head->head.class, "%s", VSM_CLASS_FREE);
VWMB();
vsm_end = (void*)((uint8_t*)VSM_head + size);
VSC_C_main = VSM_Alloc(sizeof *VSC_C_main,
VSC_CLASS, VSC_TYPE_MAIN, "");
AN(VSC_C_main);
do
VSM_head->alloc_seq = random();
while (VSM_head->alloc_seq == 0);
#endif
}
void
mgt_SHM_Pid
(
void
)
{
#if 0
VSM_head->master_pid = getpid();
#endif
}
include/vapi/vsm.h
View file @
e4d1d360
...
...
@@ -32,8 +32,16 @@
#define VAPI_VSM_H_INCLUDED
struct
VSM_head
;
struct
VSM_chunk
;
struct
VSM_data
;
struct
VSM_fantom
{
struct
VSM_chunk
*
chunk
;
void
*
b
;
void
*
e
;
uintptr_t
priv
;
};
/*---------------------------------------------------------------------
* VSM level access functions
*/
...
...
@@ -46,6 +54,7 @@ struct VSM_data *VSM_New(void);
* referencing the same or different shared memory files.
* Returns:
* Pointer to usable VSL_data handle.
* NULL: malloc failed.
*/
typedef
void
VSM_diag_f
(
void
*
priv
,
const
char
*
fmt
,
...);
...
...
@@ -66,7 +75,7 @@ int VSM_n_Arg(struct VSM_data *vd, const char *n_arg);
* and VSC_Arg() functions.
* Returns:
* 1 on success
* -1 on failure, with diagnostic
on stderr
.
* -1 on failure, with diagnostic.
*/
const
char
*
VSM_Name
(
const
struct
VSM_data
*
vd
);
...
...
include/vapi/vsm_int.h
View file @
e4d1d360
...
...
@@ -29,6 +29,67 @@
* Define the layout of the shared memory log segment.
*
* NB: THIS IS NOT A PUBLIC API TO VARNISH!
*
* There is a lot of diplomacy and protocol involved with the VSM segment
* since there is no way to (and no desire to!) lock between the readers
* and the writer.
*
* In particular we want the readers to seamlessly jump from one VSM instance
* to another when the child restarts.
*
* The VSM life-cycle there is:
*
* Manager creates VSM file under temp name
*
* Temp VSM file is initialized such that VSM_head is consistent
* with a non-zero alloc_seq
*
* Manager renames Temp VSM file to correct filename as atomic
* operation.
*
* When manager abandons VSM file, alloc_seq is set to zero, which
* never happens in any other circumstances.
*
* If a manager is started and finds and old abandonned VSM segment
* it will zero the alloc_seq in it, before replacing the file.
*
* Subscribers will have to monitor two things to make sure they have
* the current VSM instance: The alloc_seq field and the inode number
* of the path-name. The former check is by far the cheaper and the
* latter check should only be employed when lack of activity in the
* VSM segment raises suspicion that something has happened.
*
* The allocations ("chunks") in the VSM forms a linked list, starting with
* VSM_head->first, with the first/next fields being byte offsets relative
* to the start of the VSM segment.
*
* The last chunk on the list, has next == 0.
*
* New chunks are appended to the list, no matter where in the VSM
* they happen to be allocated.
*
* Chunk allocation sequence is:
* Find free space
* Zero payload
* Init Chunk header
* Write memory barrier
* update hdr->first or $last->next pointer
* hdr->alloc_seq changes
* Write memory barrier
*
* Chunk contents should be designed so that zero bytes are not mistaken
* for valid contents.
*
* Chunk deallocation sequence is:
* update hdr->first or $prev->next pointer
* Write memory barrier
* this->len = 0
* hdr->alloc_seq changes
* Write memory barrier
*
* The space occupied by the chunk is put on a cooling list and is not
* recycled for at least a minute.
*
*/
#ifndef VSM_INT_H_INCLUDED
...
...
@@ -36,80 +97,23 @@
#define VSM_FILENAME "_.vsm"
/*
* This structure describes each allocation from the shmlog
*/
struct
VSM_chunk
{
#define VSM_CHUNK_MAGIC 0xa15712e5
/* From /dev/random */
unsigned
magic
;
unsigned
len
;
/* Incl VSM_chunk */
unsigned
next
;
/* Offset in shmem */
unsigned
state
;
/* XXX remove */
ssize_t
len
;
/* Incl VSM_chunk */
ssize_t
next
;
/* Offset in shmem */
char
class
[
8
];
char
type
[
8
];
char
ident
[
64
];
};
#define VSM_NEXT(sha) ((void*)((uintptr_t)(sha) + (sha)->len))
#define VSM_PTR(sha) ((void*)((uintptr_t)((sha) + 1)))
struct
VSM_head
{
#define VSM_HEAD_MAGIC 0xe75f7e91
/* From /dev/random */
unsigned
magic
;
unsigned
hdrsize
;
unsigned
first
;
/* Offset, first chunk */
uint64_t
starttime
;
int64_t
master_pid
;
int64_t
child_pid
;
unsigned
shm_size
;
ssize_t
hdrsize
;
ssize_t
shm_size
;
ssize_t
first
;
/* Offset, first chunk */
unsigned
alloc_seq
;
/* Must be last element */
struct
VSM_chunk
head
;
};
/*
* You must include "miniobj.h" and have an assert function to be
* able to use the VSM_ITER() macro.
*/
#ifdef CHECK_OBJ_NOTNULL
extern
struct
VSM_head
*
VSM_head
;
extern
const
struct
VSM_chunk
*
vsm_end
;
static
inline
struct
VSM_chunk
*
vsm_iter_0
(
void
)
{
CHECK_OBJ_NOTNULL
(
VSM_head
,
VSM_HEAD_MAGIC
);
CHECK_OBJ_NOTNULL
(
&
VSM_head
->
head
,
VSM_CHUNK_MAGIC
);
return
(
&
VSM_head
->
head
);
}
static
inline
void
vsm_iter_n
(
struct
VSM_chunk
**
pp
)
{
CHECK_OBJ_NOTNULL
(
VSM_head
,
VSM_HEAD_MAGIC
);
CHECK_OBJ_NOTNULL
(
*
pp
,
VSM_CHUNK_MAGIC
);
*
pp
=
VSM_NEXT
(
*
pp
);
if
(
*
pp
>=
vsm_end
)
{
*
pp
=
NULL
;
return
;
}
CHECK_OBJ_NOTNULL
(
*
pp
,
VSM_CHUNK_MAGIC
);
}
#define VSM_ITER(vd) for ((vd) = vsm_iter_0(); (vd) != NULL; vsm_iter_n(&vd))
#else
#define VSM_ITER(vd) while (YOU_NEED_MINIOBJ_TO_USE_VSM_ITER)
#endif
/* CHECK_OBJ_NOTNULL */
#endif
/* VSM_INT_H_INCLUDED */
lib/libvarnishapi/vsl.c
View file @
e4d1d360
...
...
@@ -390,7 +390,8 @@ VSL_Open(struct VSM_data *vd, int diag)
/*--------------------------------------------------------------------*/
int
VSL_Matched
(
const
struct
VSM_data
*
vd
,
uint64_t
bitmap
)
int
VSL_Matched
(
const
struct
VSM_data
*
vd
,
uint64_t
bitmap
)
{
if
(
vd
->
vsl
->
num_matchers
>
0
)
{
uint64_t
t
;
...
...
lib/libvarnishapi/vsm.c
View file @
e4d1d360
...
...
@@ -62,7 +62,8 @@ VSM_New(void)
struct
VSM_data
*
vd
;
ALLOC_OBJ
(
vd
,
VSM_MAGIC
);
AN
(
vd
);
if
(
vd
==
NULL
)
return
(
vd
);
vd
->
diag
=
(
VSM_diag_f
*
)
fprintf
;
vd
->
priv
=
stderr
;
...
...
@@ -132,15 +133,22 @@ VSM_Delete(struct VSM_data *vd)
if
(
vd
->
vsl
!=
NULL
)
VSL_Delete
(
vd
);
free
(
vd
);
FREE_OBJ
(
vd
);
}
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------
* The internal VSM open function
*
* Return:
* 0 = sucess
* 1 = failure
*
*/
static
int
vsm_open
(
struct
VSM_data
*
vd
,
int
diag
)
{
int
i
,
j
;
int
i
;
struct
VSM_head
slh
;
CHECK_OBJ_NOTNULL
(
vd
,
VSM_MAGIC
);
...
...
@@ -155,7 +163,7 @@ vsm_open(struct VSM_data *vd, int diag)
return
(
1
);
}
assert
(
fstat
(
vd
->
vsm_fd
,
&
vd
->
fstat
)
==
0
);
AZ
(
fstat
(
vd
->
vsm_fd
,
&
vd
->
fstat
)
);
if
(
!
S_ISREG
(
vd
->
fstat
.
st_mode
))
{
if
(
diag
)
vd
->
diag
(
vd
->
priv
,
"%s is not a regular file
\n
"
,
...
...
@@ -174,16 +182,16 @@ vsm_open(struct VSM_data *vd, int diag)
vd
->
vsm_fd
=
-
1
;
return
(
1
);
}
if
(
slh
.
magic
!=
VSM_HEAD_MAGIC
)
{
if
(
slh
.
magic
!=
VSM_HEAD_MAGIC
||
slh
.
alloc_seq
==
0
)
{
if
(
diag
)
vd
->
diag
(
vd
->
priv
,
"
Wrong magic number in
file %s
\n
"
,
vd
->
diag
(
vd
->
priv
,
"
Not a ready VSM
file %s
\n
"
,
vd
->
fname
);
AZ
(
close
(
vd
->
vsm_fd
));
vd
->
vsm_fd
=
-
1
;
return
(
1
);
}
vd
->
VSM_head
=
(
void
*
)
mmap
(
NULL
,
slh
.
shm_size
,
vd
->
VSM_head
=
mmap
(
NULL
,
slh
.
shm_size
,
PROT_READ
,
MAP_SHARED
|
MAP_HASSEMAPHORE
,
vd
->
vsm_fd
,
0
);
if
(
vd
->
VSM_head
==
MAP_FAILED
)
{
if
(
diag
)
...
...
@@ -195,20 +203,7 @@ vsm_open(struct VSM_data *vd, int diag)
return
(
1
);
}
vd
->
vsm_end
=
(
uint8_t
*
)
vd
->
VSM_head
+
slh
.
shm_size
;
for
(
j
=
0
;
j
<
20
&&
vd
->
VSM_head
->
alloc_seq
==
0
;
j
++
)
(
void
)
usleep
(
50000
);
if
(
vd
->
VSM_head
->
alloc_seq
==
0
)
{
if
(
diag
)
vd
->
diag
(
vd
->
priv
,
"File not initialized %s
\n
"
,
vd
->
fname
);
assert
(
0
==
munmap
((
void
*
)
vd
->
VSM_head
,
slh
.
shm_size
));
AZ
(
close
(
vd
->
vsm_fd
));
vd
->
vsm_fd
=
-
1
;
vd
->
VSM_head
=
NULL
;
return
(
1
);
}
vd
->
alloc_seq
=
vd
->
VSM_head
->
alloc_seq
;
vd
->
my_alloc_seq
=
vd
->
VSM_head
->
alloc_seq
;
if
(
vd
->
vsl
!=
NULL
)
VSL_Open_CallBack
(
vd
);
...
...
@@ -238,10 +233,10 @@ VSM_Close(struct VSM_data *vd)
CHECK_OBJ_NOTNULL
(
vd
,
VSM_MAGIC
);
if
(
vd
->
VSM_head
==
NULL
)
return
;
assert
(
0
==
munmap
((
void
*
)
vd
->
VSM_head
,
vd
->
VSM_head
->
shm_size
));
AZ
(
munmap
((
void
*
)
vd
->
VSM_head
,
vd
->
VSM_head
->
shm_size
));
vd
->
VSM_head
=
NULL
;
assert
(
vd
->
vsm_fd
>=
0
);
assert
(
0
==
close
(
vd
->
vsm_fd
));
AZ
(
close
(
vd
->
vsm_fd
));
vd
->
vsm_fd
=
-
1
;
}
...
...
@@ -330,10 +325,10 @@ VSM_iter0(struct VSM_data *vd)
{
CHECK_OBJ_NOTNULL
(
vd
,
VSM_MAGIC
);
vd
->
alloc_seq
=
vd
->
VSM_head
->
alloc_seq
;
while
(
vd
->
alloc_seq
==
0
)
{
vd
->
my_
alloc_seq
=
vd
->
VSM_head
->
alloc_seq
;
while
(
vd
->
my_
alloc_seq
==
0
)
{
(
void
)
usleep
(
50000
);
vd
->
alloc_seq
=
vd
->
VSM_head
->
alloc_seq
;
vd
->
my_
alloc_seq
=
vd
->
VSM_head
->
alloc_seq
;
}
CHECK_OBJ_NOTNULL
(
&
vd
->
VSM_head
->
head
,
VSM_CHUNK_MAGIC
);
return
(
&
vd
->
VSM_head
->
head
);
...
...
@@ -344,7 +339,7 @@ VSM_itern(const struct VSM_data *vd, struct VSM_chunk **pp)
{
CHECK_OBJ_NOTNULL
(
vd
,
VSM_MAGIC
);
if
(
vd
->
alloc_seq
!=
vd
->
VSM_head
->
alloc_seq
)
{
if
(
vd
->
my_
alloc_seq
!=
vd
->
VSM_head
->
alloc_seq
)
{
*
pp
=
NULL
;
return
;
}
...
...
lib/libvarnishapi/vsm_api.h
View file @
e4d1d360
...
...
@@ -44,13 +44,12 @@ struct VSM_data {
char
*
n_opt
;
char
*
fname
;
struct
stat
fstat
;
int
vsm_fd
;
struct
VSM_head
*
VSM_head
;
void
*
vsm_end
;
unsigned
alloc_seq
;
unsigned
my_
alloc_seq
;
/* Stuff relating the stats fields start here */
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment