12 #include <portals/list.h>
15 #include <snapfs_internal.h>
17 #define IOC_BUF_MAX_LEN 8192
18 static char rawbuf[IOC_BUF_MAX_LEN];
19 static char *buf = rawbuf;
20 /*FIXME add this temporary, will use obd_ioc_data later*/
21 #define IOC_INIT(ptr) \
23 struct ioc_data* pbuf; \
24 memset(buf, 0, sizeof(rawbuf)); \
25 pbuf = (struct ioc_data*)buf; \
26 pbuf->ioc_inbuf = pbuf->ioc_bulk; \
27 ptr = (struct ioc_snap_tbl_data *)pbuf->ioc_bulk; \
30 #define IOC_PACK(length) \
32 struct ioc_data* pbuf; \
33 pbuf = (struct ioc_data*)buf; \
34 pbuf->ioc_inlen = length; \
37 static struct list_head snap_list;
38 struct open_snap_device open_device_table;
39 struct snap_device snap_device_list[10];
42 static int get_snaplist()
44 FILE *mnt_filp = NULL;
48 mnt_filp = setmntent("/etc/mtab", "r");
52 /*get the mentent and check snap mount*/
53 while (!feof(mnt_filp)) {
56 entry = getmntent(mnt_filp);
60 if (!strcmp(entry->mnt_type, "snap_current")) {
61 /*found a snap_mount structure add to the snaplist*/
62 struct snap_mnt *s_mnt;
64 char dev_name[DEV_NAME_MAX_LEN];
67 s_mnt = (struct snap_mnt *) malloc(sizeof(struct snap_mnt));
72 memset(s_mnt, 0, sizeof(struct snap_mnt));
73 memcpy(&s_mnt->device.name[0], entry->mnt_fsname, strlen(entry->mnt_fsname));
74 memcpy(&s_mnt->device.mntpt[0], entry->mnt_dir, strlen(entry->mnt_dir));
75 opt = hasmntopt(entry, "loop");
76 memset(dev_name, 0, DEV_NAME_MAX_LEN);
78 /* Loop device mount find the real dev_name*/
79 char *name = opt, *name_dev = dev_name;
81 while (*name++ != '=');
82 while (*name != ',' && *name != ')' && *name ) {
83 *name_dev++ = *name++;
87 memcpy(dev_name, entry->mnt_fsname, strlen(entry->mnt_fsname));
90 if ((error = stat(dev_name, &statbuf)) != 0) {
91 fprintf(stderr, "can not stat %s", strerror(errno));
94 s_mnt->device.dev = (unsigned long)statbuf.st_rdev;
95 list_add(&s_mnt->snap_mnt_list, &snap_list);
104 static void release_snap_list()
106 struct snap_mnt *snaplist;
108 list_for_each_entry(snaplist, &snap_list, snap_mnt_list) {
109 list_del(&snaplist->snap_mnt_list);
114 void init_snap_list()
118 INIT_LIST_HEAD(&snap_list);
119 open_device_table.count = 0;
120 for(i = 0; i < 10; i++) {
121 memset(&open_device_table.device[i].name[0],
122 0, DEV_NAME_MAX_LEN);
123 open_device_table.device[i].fd = -1;
127 static int open_device(char *name, unsigned int dev)
129 int index=0, error = 0, i = 0, found = 0;
131 /*XXX Does these information necessary*/
132 for (i = 0; i < open_device_table.count; i++) {
133 if (!strcmp(&open_device_table.device[i].name[0], name)) {
140 open_device_table.device[index].dev = dev;
141 memset(&open_device_table.device[index].name[0],
142 0, DEV_NAME_MAX_LEN);
143 memcpy(&open_device_table.device[index].name[0],
145 open_device_table.count ++;
147 /*FIXME If there are more than device, how to handle it*/
148 if (open_device_table.device[index].fd < 0) {
150 int fd = open(SNAPDEV_NAME, O_RDWR);
153 if (errno == ENOENT) {
154 dev_t snap_dev=makedev(SNAP_PSDEV_MAJOR,SNAP_PSDEV_MINOR);
155 /*create snapdevice node*/
156 error = mknod(SNAPDEV_NAME, S_IRUSR|S_IWUSR|S_IFCHR, snap_dev);
158 fprintf(stderr, "Can not make node %s :%s \n",
159 SNAPDEV_NAME, strerror(errno));
162 if ((fd = open(SNAPDEV_NAME, O_RDWR)) < 0) {
163 fprintf(stderr, "Can not open node %s: %s\n",
164 SNAPDEV_NAME, strerror(errno));
168 fprintf(stderr, "Can not open node %s: %s %d \n",
169 SNAPDEV_NAME, strerror(errno), errno);
173 open_device_table.device[index].fd = fd;
178 int snap_dev_open(int argc, char **argv)
180 struct snap_mnt *snaplist;
185 fprintf(stderr, "The argument count is not right \n");
192 list_for_each_entry(snaplist, &snap_list, snap_mnt_list) {
193 if (!strcmp(&snaplist->device.name[0], dev_name)) {
194 rc = open_device(&snaplist->device.name[0],
195 snaplist->device.dev);
201 fprintf(stderr, "%s are not snapdevice\n", dev_name);
204 int snap_dev_list(int argc, char **argv)
206 struct snap_mnt *snaplist;
210 fprintf(stderr, "The argument count is not right \n");
215 printf("index:\t\tmount_point:\t\tdevice:\n");
216 list_for_each_entry(snaplist, &snap_list, snap_mnt_list) {
217 printf("%d\t\t%s\t\t%s \n", index,
218 &snaplist->device.mntpt[0],
219 &snaplist->device.name[0]);
225 static inline void print_snap_table(void * buf)
227 struct ioc_snap_tbl_data *ptable;
230 ptable = (struct ioc_snap_tbl_data*)buf;
232 printf("There are %d snapshot in the system\n", ptable->count);
233 printf("index\t\tname\t\t\ttime\t\t\n");
234 for (i = 0; i < ptable->count; i++) {
235 struct tm* local_time;
238 memset (time, 0, sizeof(time));
239 local_time = localtime(&ptable->snaps[i].time);
241 strftime(time, sizeof(time), "%a %b %d %Y %H:%M:%S", local_time);
242 printf("%-10d\t%-20s\t%s\n", ptable->snaps[i].index, ptable->snaps[i].name, time);
245 int snap_snap_list(int argc, char **argv)
249 if (argc != 1 && argc != 2) {
250 fprintf(stderr, "The argument count is not right\n");
253 if (open_device_table.count == 0) {
254 fprintf(stderr, "Please open a snapdevice first\n");
258 for (i = 0; i < open_device_table.count; i++) {
259 struct ioc_snap_tbl_data *snap_ioc_data;
261 IOC_INIT(snap_ioc_data);
264 snap_ioc_data->no = atoi(argv[1]);
266 snap_ioc_data->no = 0;
269 IOC_PACK(sizeof(struct ioc_snap_tbl_data));
271 if ((rc = ioctl(open_device_table.device[i].fd,
272 IOC_SNAP_PRINTTABLE, buf))) {
273 fprintf(stderr, "can not retrive snaptable on device %s failed %d \n",
274 &open_device_table.device[i].name[0], rc);
277 if(((struct ioc_data*)buf)->ioc_bulk)
278 print_snap_table(((struct ioc_data*)buf)->ioc_bulk);
282 int snap_snap_add(int argc, char **argv)
286 if (argc != 3 && argc !=2) {
287 fprintf(stderr, "The argument count is not right \n");
291 if (open_device_table.count == 0) {
292 fprintf(stderr, "Please open a snapdevice first\n");
295 for (i = 0; i < open_device_table.count; i++) {
296 struct ioc_snap_tbl_data *snap_ioc_data;
298 IOC_INIT(snap_ioc_data);
300 snap_ioc_data->count = 1;
301 snap_ioc_data->dev = open_device_table.device[i].dev;
304 snap_ioc_data->no = atoi(argv[1]);
305 memcpy(snap_ioc_data->snaps[0].name,
306 argv[2], strlen(argv[2]));
308 snap_ioc_data->no = 0;
309 memcpy(snap_ioc_data->snaps[0].name,
310 argv[1], strlen(argv[1]));
312 snap_ioc_data->snaps[0].time = time(NULL);
314 IOC_PACK(sizeof(struct ioc_snap_tbl_data) + sizeof(struct snap));
316 if ((rc = ioctl(open_device_table.device[i].fd,
317 IOC_SNAP_ADD, buf))) {
318 fprintf(stderr, "add %s failed \n", argv[1]);
320 fprintf(stderr, "add %s success\n", argv[1]);