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;
177 static int open_snap_device(char *name)
179 struct snap_mnt *snaplist;
182 list_for_each_entry(snaplist, &snap_list, snap_mnt_list) {
183 if (!strcmp(&snaplist->device.name[0], name)) {
184 rc = open_device(&snaplist->device.name[0],
185 snaplist->device.dev);
191 fprintf(stderr, "%s are not snapdevice\n", name);
194 int snap_dev_open(int argc, char **argv)
200 fprintf(stderr, "The argument count is not right \n");
205 rc = open_snap_device(dev_name);
207 fprintf(stderr, "%s are not snapdevice\n", dev_name);
210 int snap_dev_list(int argc, char **argv)
212 struct snap_mnt *snaplist;
216 fprintf(stderr, "The argument count is not right \n");
221 printf("index:\t\tmount_point:\t\tdevice:\n");
222 list_for_each_entry(snaplist, &snap_list, snap_mnt_list) {
223 printf("%d\t\t%s\t\t%s \n", index,
224 &snaplist->device.mntpt[0],
225 &snaplist->device.name[0]);
231 static inline void print_snap_table(void * buf)
233 struct ioc_snap_tbl_data *ptable;
236 ptable = (struct ioc_snap_tbl_data*)buf;
238 printf("There are %d snapshot in the system\n", ptable->count);
239 printf("index\t\tname\t\t\ttime\t\t\n");
240 for (i = 0; i < ptable->count; i++) {
241 struct tm* local_time;
244 memset (time, 0, sizeof(time));
245 local_time = localtime(&ptable->snaps[i].time);
247 strftime(time, sizeof(time), "%a %b %d %Y %H:%M:%S", local_time);
248 printf("%-10d\t%-20s\t%s\n", ptable->snaps[i].index, ptable->snaps[i].name, time);
251 int snap_snap_list(int argc, char **argv)
253 char *dev_name = NULL;
256 if (argc != 1 && argc != 2) {
257 fprintf(stderr, "The argument count is not right\n");
260 if (open_device_table.count == 0) {
265 rc = open_snap_device(dev_name);
267 if (!dev_name || rc) {
268 fprintf(stderr, "Please open a snapdevice first\n");
272 for (i = 0; i < open_device_table.count; i++) {
273 struct ioc_snap_tbl_data *snap_ioc_data;
275 IOC_INIT(snap_ioc_data);
278 snap_ioc_data->no = atoi(argv[1]);
280 snap_ioc_data->no = 0;
283 IOC_PACK(sizeof(struct ioc_snap_tbl_data));
285 if ((rc = ioctl(open_device_table.device[i].fd,
286 IOC_SNAP_PRINTTABLE, buf))) {
287 fprintf(stderr, "can not retrive snaptable on device %s failed %d \n",
288 &open_device_table.device[i].name[0], rc);
291 if(((struct ioc_data*)buf)->ioc_bulk)
292 print_snap_table(((struct ioc_data*)buf)->ioc_bulk);
296 int snap_snap_del(int argc, char **argv)
298 char *dev_name = NULL, *snap_name = NULL;
301 if (argc != 3 && argc !=2) {
302 fprintf(stderr, "The argument count is not right \n");
305 if (open_device_table.count == 0) {
308 } else if (argc == 4) {
312 rc = open_snap_device(dev_name);
314 if (!dev_name || rc) {
315 fprintf(stderr, "Please open a snapdevice first\n");
319 for (i = 0; i < open_device_table.count; i++) {
320 struct ioc_snap_tbl_data *snap_ioc_data;
322 IOC_INIT(snap_ioc_data);
324 snap_ioc_data->count = 1;
325 snap_ioc_data->dev = open_device_table.device[i].dev;
328 snap_ioc_data->no = atoi(argv[1]);
332 snap_ioc_data->no = 0;
336 memcpy(snap_ioc_data->snaps[0].name,
337 snap_name, strlen(snap_name));
339 snap_ioc_data->snaps[0].time = time(NULL);
341 IOC_PACK(sizeof(struct ioc_snap_tbl_data) + sizeof(struct snap));
343 if ((rc = ioctl(open_device_table.device[i].fd,
344 IOC_SNAP_DELETE, buf))) {
345 fprintf(stderr, "del %s failed \n", snap_name);
347 fprintf(stderr, "del %s success\n", snap_name);
352 int snap_snap_add(int argc, char **argv)
354 char *dev_name = NULL, *snap_name = NULL;
357 if (argc != 3 && argc !=2 && argc !=4) {
358 fprintf(stderr, "The argument count is not right \n");
361 if (open_device_table.count == 0) {
365 } else if (argc == 4) {
370 rc = open_snap_device(dev_name);
372 if (!dev_name || rc) {
373 fprintf(stderr, "Please open a snapdevice first\n");
377 for (i = 0; i < open_device_table.count; i++) {
378 struct ioc_snap_tbl_data *snap_ioc_data;
380 IOC_INIT(snap_ioc_data);
382 snap_ioc_data->count = 1;
383 snap_ioc_data->dev = open_device_table.device[i].dev;
386 snap_ioc_data->no = atoi(argv[1]);
390 snap_ioc_data->no = 0;
394 memcpy(snap_ioc_data->snaps[0].name,
395 snap_name, strlen(snap_name));
396 snap_ioc_data->snaps[0].time = time(NULL);
398 IOC_PACK(sizeof(struct ioc_snap_tbl_data) + sizeof(struct snap));
400 if ((rc = ioctl(open_device_table.device[i].fd,
401 IOC_SNAP_ADD, buf))) {
402 fprintf(stderr, "add %s failed \n", snap_name);
404 fprintf(stderr, "add %s success\n", snap_name);