~serge-hallyn/ubuntu/precise/lxc/lxc-dnsmasq

« back to all changes in this revision

Viewing changes to debian/patches/0053-lxc-start-pin-rootfs

  • Committer: Serge Hallyn
  • Date: 2012-02-28 20:14:32 UTC
  • Revision ID: serge.hallyn@ubuntu.com-20120228201432-05cpfto4s6ncqstk
get the rootfs pinning working

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
5
 
Forwarded: yes
6
 
 
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
11
 
@@ -445,6 +445,40 @@
 
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
 
5
@@ -445,6 +445,51 @@
12
6
        return mount_unknow_fs(rootfs, target, 0);
13
7
 }
14
8
 
 
9
+/*
 
10
+ * pin_rootfs
 
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.
 
17
+ */
15
18
+int pin_rootfs(const char *rootfs)
16
19
+{
17
20
+       char absrootfs[MAXPATHLEN];
18
21
+       char absrootfspin[MAXPATHLEN];
19
22
+       struct stat s;
 
23
+       int ret, fd;
20
24
+
21
25
+       if (!realpath(rootfs, absrootfs)) {
22
26
+               SYSERROR("failed to get real path for '%s'", rootfs);
34
38
+       }
35
39
+
36
40
+       if (!__S_ISTYPE(s.st_mode, S_IFDIR))
37
 
+               return 0;
 
41
+               return -2;
38
42
+
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");
42
46
+               return -1;
43
47
+       }
44
48
+
45
 
+       fd = open(absrootfspin, "w");
46
 
+       return 0;
 
49
+       fd = open(absrootfspin, O_CREAT | O_RDWR, S_IWUSR|S_IRUSR);
 
50
+       INFO("opened %s as fd %d\n", absrootfspin, fd);
 
51
+       return fd;
47
52
+}
48
53
+
49
54
 static int mount_rootfs(const char *rootfs, const char *target)
50
55
 {
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 @@
57
62
  */
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
69
 
@@ -611,6 +611,14 @@
70
 
                }
 
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
 
74
@@ -565,6 +565,7 @@
 
75
        int clone_flags;
 
76
        int failed_before_rename = 0;
 
77
        const char *name = handler->name;
 
78
+       int pinfd;
 
79
 
 
80
        if (lxc_sync_init(handler))
 
81
                return -1;
 
82
@@ -585,6 +586,17 @@
71
83
        }
72
84
 
 
85
 
73
86
+       /*
74
87
+        * if the rootfs is not a blockdev, prevent the container from
75
88
+        * marking it readonly.
76
89
+        */
77
90
+
78
 
+       struct lxc_rootfs *rootfs = handler->conf->rootfs;
79
 
+       if (rootfs->path
80
 
+
81
 
        /* Tell the child to continue its initialization and wait for
82
 
         * it to exec or return an error
83
 
         */
 
91
+       pinfd = pin_rootfs(handler->conf->rootfs.path);
 
92
+       if (pinfd == -1) {
 
93
+               ERROR("failed to pin the container's rootfs");
 
94
+               goto out_abort;
 
95
+       }
 
96
+
 
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) {
 
100
@@ -627,6 +639,10 @@
 
101
        }
 
102
 
 
103
        lxc_sync_fini(handler);
 
104
+
 
105
+       if (pinfd >= 0)
 
106
+               close(pinfd);
 
107
+
 
108
        return 0;
 
109
 
 
110
 out_delete_net: