1
Description: if rootfs is a dir, pin the fs
2
Otherwise the container can remount the shared underlying fs readonly.
3
Author: Serge Hallyn <serge.hallyn@ubuntu.com>
4
Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/lxc/+bug/942325
7
Index: lxc/src/lxc/conf.c
1
Index: lxc-dnsmasq/src/lxc/conf.c
8
2
===================================================================
9
--- lxc.orig/src/lxc/conf.c 2012-02-28 13:01:18.350610000 -0600
10
+++ lxc/src/lxc/conf.c 2012-02-28 13:01:48.597583908 -0600
3
--- lxc-dnsmasq.orig/src/lxc/conf.c 2012-02-28 19:13:01.400960000 +0000
4
+++ lxc-dnsmasq/src/lxc/conf.c 2012-02-28 20:05:45.538144907 +0000
12
6
return mount_unknow_fs(rootfs, target, 0);
11
+ * if rootfs is a directory, then open ${rootfs}.hold for writing for the
12
+ * duration of the container run, to prevent the container from marking the
13
+ * underlying fs readonly on shutdown.
14
+ * return -1 on error.
15
+ * return -2 if nothing needed to be pinned.
16
+ * return an open fd (>=0) if we pinned it.
15
18
+int pin_rootfs(const char *rootfs)
17
20
+ char absrootfs[MAXPATHLEN];
18
21
+ char absrootfspin[MAXPATHLEN];
21
25
+ if (!realpath(rootfs, absrootfs)) {
22
26
+ SYSERROR("failed to get real path for '%s'", rootfs);
36
40
+ if (!__S_ISTYPE(s.st_mode, S_IFDIR))
39
+ ret = snprintf(absrootfspin, "%s/%s", absrootfs, ".hold");
43
+ ret = snprintf(absrootfspin, MAXPATHLEN, "%s%s", absrootfs, ".hold");
40
44
+ if (ret >= MAXPATHLEN) {
41
45
+ SYSERROR("pathname too long for rootfs hold file");
45
+ fd = open(absrootfspin, "w");
49
+ fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR);
50
+ INFO("opened %s as fd %d\n", absrootfspin, fd);
49
54
static int mount_rootfs(const char *rootfs, const char *target)
51
56
char absrootfs[MAXPATHLEN];
52
Index: lxc/src/lxc/conf.h
57
Index: lxc-dnsmasq/src/lxc/conf.h
53
58
===================================================================
54
--- lxc.orig/src/lxc/conf.h 2012-02-23 16:21:13.750796000 -0600
55
+++ lxc/src/lxc/conf.h 2012-02-28 13:07:34.467298977 -0600
59
--- lxc-dnsmasq.orig/src/lxc/conf.h 2012-02-28 19:13:01.400960000 +0000
60
+++ lxc-dnsmasq/src/lxc/conf.h 2012-02-28 19:13:01.400960000 +0000
56
61
@@ -218,6 +218,8 @@
58
63
extern struct lxc_conf *lxc_conf_init(void);
62
67
extern int lxc_create_network(struct lxc_handler *handler);
63
68
extern void lxc_delete_network(struct lxc_list *networks);
64
69
extern int lxc_assign_network(struct lxc_list *networks, pid_t pid);
65
Index: lxc/src/lxc/start.c
70
Index: lxc-dnsmasq/src/lxc/start.c
66
71
===================================================================
67
--- lxc.orig/src/lxc/start.c 2012-02-28 13:01:18.350610000 -0600
68
+++ lxc/src/lxc/start.c 2012-02-28 13:08:00.443427796 -0600
72
--- lxc-dnsmasq.orig/src/lxc/start.c 2012-02-28 19:13:01.400960000 +0000
73
+++ lxc-dnsmasq/src/lxc/start.c 2012-02-28 20:07:41.174882442 +0000
76
int failed_before_rename = 0;
77
const char *name = handler->name;
80
if (lxc_sync_init(handler))
74
87
+ * if the rootfs is not a blockdev, prevent the container from
75
88
+ * marking it readonly.
78
+ struct lxc_rootfs *rootfs = handler->conf->rootfs;
81
/* Tell the child to continue its initialization and wait for
82
* it to exec or return an error
91
+ pinfd = pin_rootfs(handler->conf->rootfs.path);
93
+ ERROR("failed to pin the container's rootfs");
97
/* Create a process in a new set of namespaces */
98
handler->pid = lxc_clone(do_start, handler, clone_flags);
99
if (handler->pid < 0) {
103
lxc_sync_fini(handler);