| 148 | } |
| 149 | |
| 150 | static bool |
| 151 | lock_box(bool is_init, bool is_cleanup) |
| 152 | { |
| 153 | if (!dir_exists(cf_lock_root)) |
| 154 | make_dir(cf_lock_root); |
| 155 | |
| 156 | char lock_name[256]; |
| 157 | int name_len = snprintf(lock_name, sizeof(lock_name), "%s/%d", cf_lock_root, box_id); |
| 158 | assert(name_len < (int) sizeof(lock_name)); |
| 159 | |
| 160 | lock_fd = open(lock_name, O_RDWR | (is_init ? O_CREAT : 0), 0666); |
| 161 | if (lock_fd < 0) |
| 162 | { |
| 163 | if (errno == ENOENT) |
| 164 | return false; |
| 165 | die("Cannot open %s: %m", lock_name); |
| 166 | } |
| 167 | |
| 168 | if (flock(lock_fd, LOCK_EX | (wait_if_busy ? 0 : LOCK_NB)) < 0) |
| 169 | { |
| 170 | if (errno == EWOULDBLOCK) |
| 171 | die("This box is currently in use by another process"); |
| 172 | die("Cannot lock %s: %m", lock_name); |
| 173 | } |
| 174 | |
| 175 | int n = read(lock_fd, &lock, sizeof(lock)); |
| 176 | if (n < 0) |
| 177 | die("Cannot read %s: %m", lock_name); |
| 178 | |
| 179 | if (n > 0) |
| 180 | { |
| 181 | if (n != sizeof(lock) || lock.magic != LOCK_MAGIC) |
| 182 | die("Lock file %s has incompatible format", lock_name); |
| 183 | if (lock.is_initialized && lock.owner_uid != orig_uid && !invoked_by_root) |
| 184 | die("This box belongs to a different user (uid %d)", lock.owner_uid); |
| 185 | if (lock.cg_enabled != cg_enable) |
| 186 | die("This box was initialized with an incompatible control group mode"); |
| 187 | } |
| 188 | |
| 189 | if (is_init) |
| 190 | { |
| 191 | lock.magic = LOCK_MAGIC; |
| 192 | lock.owner_uid = orig_uid; |
| 193 | lock.cg_enabled = cg_enable; |
| 194 | lock.is_initialized = 0; |
| 195 | lock_write(); |
| 196 | return true; |
| 197 | } |
| 198 | else |
| 199 | { |
| 200 | if (n > 0) |
| 201 | { |
| 202 | if (!lock.is_initialized && !is_cleanup) |
| 203 | die("This box was not initialized properly"); |
| 204 | return true; |
| 205 | } |
| 206 | else |
| 207 | { |
no test coverage detected
searching dependent graphs…