static int do_freeze_thaw(bool freeze, const char *name, const char *lxcpath) { int ret; char v[100]; const char *state = freeze ? "FROZEN" : "THAWED"; size_t state_len = 6; lxc_state_t new_state = freeze ? FROZEN : THAWED; ret = lxc_cgroup_set("freezer.state", state, name, lxcpath); if (ret < 0) { ERROR("Failed to freeze %s", name); return -1; } for (;;) { ret = lxc_cgroup_get("freezer.state", v, sizeof(v), name, lxcpath); if (ret < 0) { ERROR("Failed to get freezer state of %s", name); return -1; } v[99] = '\0'; v[lxc_char_right_gc(v, strlen(v))] = '\0'; ret = strncmp(v, state, state_len); if (ret == 0) { lxc_cmd_serve_state_clients(name, lxcpath, new_state); lxc_monitor_send_state(name, new_state, lxcpath); return 0; } sleep(1); } }
static int do_freeze_thaw(int freeze, const char *name, const char *lxcpath) { char v[100]; const char *state = freeze ? "FROZEN" : "THAWED"; if (lxc_cgroup_set("freezer.state", state, name, lxcpath) < 0) { ERROR("Failed to freeze %s:%s", lxcpath, name); return -1; } while (1) { if (lxc_cgroup_get("freezer.state", v, 100, name, lxcpath) < 0) { ERROR("Failed to get new freezer state for %s:%s", lxcpath, name); return -1; } if (v[strlen(v)-1] == '\n') v[strlen(v)-1] = '\0'; if (strncmp(v, state, strlen(state)) == 0) { if (name) lxc_monitor_send_state(name, freeze ? FROZEN : THAWED, lxcpath); return 0; } sleep(1); } }
int lxc_set_state(const char *name, struct lxc_handler *handler, lxc_state_t state) { handler->state = state; lxc_monitor_send_state(name, state, handler->lxcpath); return 0; }
static int do_unfreeze(const char *nsgroup, int freeze, const char *name, const char *lxcpath) { char freezer[MAXPATHLEN], *f; char tmpf[32]; int fd, ret; ret = snprintf(freezer, MAXPATHLEN, "%s/freezer.state", nsgroup); if (ret >= MAXPATHLEN) { ERROR("freezer.state name too long"); return -1; } fd = open(freezer, O_RDWR); if (fd < 0) { SYSERROR("failed to open freezer at '%s'", nsgroup); return -1; } if (freeze) { f = "FROZEN"; ret = write(fd, f, strlen(f) + 1); } else { f = "THAWED"; ret = write(fd, f, strlen(f) + 1); /* compatibility code with old freezer interface */ if (ret < 0) { f = "RUNNING"; ret = write(fd, f, strlen(f) + 1) < 0; } } if (ret < 0) { SYSERROR("failed to write '%s' to '%s'", f, freezer); goto out; } while (1) { ret = lseek(fd, 0L, SEEK_SET); if (ret < 0) { SYSERROR("failed to lseek on file '%s'", freezer); goto out; } ret = read(fd, tmpf, sizeof(tmpf)); if (ret < 0) { SYSERROR("failed to read to '%s'", freezer); goto out; } ret = strncmp(f, tmpf, strlen(f)); if (!ret) { if (name) lxc_monitor_send_state(name, freeze ? FROZEN : THAWED, lxcpath); break; /* Success */ } sleep(1); ret = lseek(fd, 0L, SEEK_SET); if (ret < 0) { SYSERROR("failed to lseek on file '%s'", freezer); goto out; } ret = write(fd, f, strlen(f) + 1); if (ret < 0) { SYSERROR("failed to write '%s' to '%s'", f, freezer); goto out; } } out: close(fd); return ret; }
int lxc_freeze(const char *name, const char *lxcpath) { lxc_monitor_send_state(name, FREEZING, lxcpath); return freeze_unfreeze(name, 1, lxcpath); }
int lxc_freeze(const char *name, const char *lxcpath) { lxc_monitor_send_state(name, FREEZING, lxcpath); return do_freeze_thaw(1, name, lxcpath); }
int lxc_freeze(const char *name, const char *lxcpath) { lxc_cmd_serve_state_clients(name, lxcpath, FREEZING); lxc_monitor_send_state(name, FREEZING, lxcpath); return do_freeze_thaw(true, name, lxcpath); }